From b7a687b08e32adafbb609bec7aa79b54f161ee4c Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Sat, 20 Dec 2008 02:01:44 +0000 Subject: All of the basic, core workings of the Cache are complete, and tested. Even added some more tests and whatnot. A lot happened, but I can't remember everything. Also, Bu::File reports errors in more error cases. --- src/cache.h | 55 +++++++++++++++++++++++++++++++---------------------- src/cachecalc.h | 26 ++++++++++++++++++++++++- src/file.cpp | 10 ++++++++-- src/list.h | 16 ++++++++++++++++ src/tests/cache.cpp | 27 +++++++++++++++++++++++++- src/trace.cpp | 1 - src/unit/hash.cpp | 21 ++++++++++++++++++++ 7 files changed, 128 insertions(+), 28 deletions(-) diff --git a/src/cache.h b/src/cache.h index cc13fc8..313d9fa 100644 --- a/src/cache.h +++ b/src/cache.h @@ -7,7 +7,6 @@ #include "bu/cachestore.h" #include "bu/cachecalc.h" -#define BU_TRACE #include "bu/trace.h" namespace Bu @@ -32,10 +31,11 @@ namespace Bu typedef Bu::Hash CidHash; public: - Cache() : - pCalc( NULL ) + Cache( Calc &rCalc ) : + rCalc( rCalc ) { TRACE(); + rCalc.setCache( this ); } virtual ~Cache() @@ -50,7 +50,7 @@ namespace Bu __tracer_format( i.getKey() ); printf("!\n"); } - if( pCalc ) pCalc->onUnload( + rCalc.onUnload( i.getValue().pData, i.getKey() ); @@ -78,16 +78,6 @@ namespace Bu lStore.prepend( pHand ); } - void setCalc( Calc *pCalc ) - { - TRACE(); - if( this->pCalc ) - { - delete this->pCalc; - } - this->pCalc = pCalc; - } - Ptr insert( obtype *pData ) { TRACE( pData ); @@ -95,7 +85,7 @@ namespace Bu keytype k = lStore.first()->create( pData ); hEnt.insert( k, e ); - if( pCalc ) pCalc->onLoad( pData, k ); + rCalc.onLoad( pData, k ); return Ptr( *this, pData, k ); } @@ -108,6 +98,7 @@ namespace Bu } catch( Bu::HashException &e ) { CacheEntry e = {lStore.first()->load( cId ), 0}; + rCalc.onLoad( e.pData, cId ); hEnt.insert( cId, e ); return Ptr( *this, e.pData, cId ); } @@ -115,9 +106,33 @@ namespace Bu int getRefCount( const keytype &cId ) { + TRACE( cId ); return hEnt.get( cId ).iRefs; } + void unload( const keytype &cId ) + { + TRACE( cId ); + try { + if( hEnt.get( cId ).iRefs > 0 ) + { + printf("Shouldn't delete, references still exist!\n"); + return; + } + } + catch( Bu::HashException &e ) { + // It's not here? Eh, return. + return; + } + obtype *pObj = hEnt.get( cId ).pData; + rCalc.onUnload( pObj, cId ); + hEnt.erase( cId ); + + // The unload has to happen last just in case cId is a reference + // to data that is about to be deleted from memory by the unload. + lStore.first()->unload( pObj, cId ); + } + void erase( const keytype &cId ) { TRACE( cId ); @@ -132,18 +147,12 @@ namespace Bu get( cId ); } - if( pCalc ) pCalc->onUnload( hEnt.get( cId ).pData, cId ); + rCalc.onUnload( hEnt.get( cId ).pData, cId ); lStore.first()->destroy( hEnt.get( cId ).pData, cId ); hEnt.erase( cId ); } - int getRefCnt( keytype cId ) - { - TRACE( cId ); - return hEnt.get( cId ).iRefs; - } - private: void incRef( keytype cId ) { @@ -161,7 +170,7 @@ namespace Bu private: CidHash hEnt; StoreList lStore; - Calc *pCalc; + Calc &rCalc; }; }; diff --git a/src/cachecalc.h b/src/cachecalc.h index 289c4ac..dd9712f 100644 --- a/src/cachecalc.h +++ b/src/cachecalc.h @@ -1,25 +1,49 @@ #ifndef BU_CACHE_CALC_H #define BU_CACHE_CALC_H +#include "bu/trace.h" + namespace Bu { + template class Cache; + template class CacheCalc { + friend class Cache; + private: + typedef Cache MyCache; public: - CacheCalc() + CacheCalc() : + pCache( (MyCache *)0 ) { + TRACE(); } virtual ~CacheCalc() { + TRACE(); } virtual void onLoad( obtype *pSrc, const keytype &key )=0; virtual void onUnload( obtype *pSrc, const keytype &key )=0; virtual void onTick() { }; + protected: + MyCache *getCache() + { + TRACE(); + return pCache; + } + private: + void setCache( MyCache *pCache ) + { + TRACE(); + this->pCache = pCache; + } + + MyCache *pCache; }; }; diff --git a/src/file.cpp b/src/file.cpp index 6e9d47e..7c18a06 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -54,7 +54,10 @@ size_t Bu::File::read( void *pBuf, size_t nBytes ) if( fd < 0 ) throw FileException("File not open."); - return ::read( fd, pBuf, nBytes ); + ssize_t iRead = ::read( fd, pBuf, nBytes ); + if( iRead < 0 ) + throw FileException( errno, "%s", strerror( errno ) ); + return iRead; } size_t Bu::File::write( const void *pBuf, size_t nBytes ) @@ -62,7 +65,10 @@ size_t Bu::File::write( const void *pBuf, size_t nBytes ) if( fd < 0 ) throw FileException("File not open."); - return ::write( fd, pBuf, nBytes ); + ssize_t iWrote = ::write( fd, pBuf, nBytes ); + if( iWrote < 0 ) + throw FileException( errno, "%s", strerror( errno ) ); + return iWrote; } long Bu::File::tell() diff --git a/src/list.h b/src/list.h index e5d7ceb..530d858 100644 --- a/src/list.h +++ b/src/list.h @@ -531,6 +531,22 @@ namespace Bu } } + /** + * Erase an item from the list if you already know the item. + *@param ob The item to find and erase. + */ + void erase( const value &v ) + { + for( iterator i = begin(); i != end(); i++ ) + { + if( (*i) == v ) + { + erase( i ); + return; + } + } + } + /** * Get the current size of the list. *@returns (int) The current size of the list. diff --git a/src/tests/cache.cpp b/src/tests/cache.cpp index 18e6a95..12b5bf4 100644 --- a/src/tests/cache.cpp +++ b/src/tests/cache.cpp @@ -7,6 +7,7 @@ #include "bu/cache.h" #include "bu/file.h" #include "bu/fstring.h" +#include "bu/cachecalc.h" class Bob { @@ -136,6 +137,29 @@ private: long cLastId; }; +class BobCalc : public Bu::CacheCalc +{ +public: + BobCalc() + { + } + + virtual ~BobCalc() + { + } + + virtual void onLoad( Bob *, const long & ) + { + } + + virtual void onUnload( Bob *, const long & ) + { + } + +private: + +}; + int main( int argc, char *argv[] ) { TRACE( argc, argv ); @@ -148,7 +172,8 @@ int main( int argc, char *argv[] ) return 0; } - BobCache cBob; + BobCalc cc; + BobCache cBob( cc ); cBob.appendStore( new BobStore() ); switch( argv[1][0] ) { diff --git a/src/trace.cpp b/src/trace.cpp index 242d110..b5f11f1 100644 --- a/src/trace.cpp +++ b/src/trace.cpp @@ -1,4 +1,3 @@ -#define BU_TRACE #include "bu/trace.h" void Bu::__tracer( const char *pf ) diff --git a/src/unit/hash.cpp b/src/unit/hash.cpp index de4edd1..77160e3 100644 --- a/src/unit/hash.cpp +++ b/src/unit/hash.cpp @@ -24,6 +24,7 @@ public: addTest( Unit::insert1 ); addTest( Unit::insert2 ); addTest( Unit::probe1 ); + addTest( Unit::erase1 ); } virtual ~Unit() @@ -66,6 +67,26 @@ public: unitTest( h3["Hi"].getValue() = "Yo" ); unitTest( h3["Bye"].getValue() = "Later" ); } + + void erase1() + { + StrIntHash h; + h.insert("Number 1", 1 ); + h.insert("Number 2", 2 ); + h.insert("Number 3", 3 ); + h.erase("Number 2"); + h.get("Number 3"); + try { + h.get("Number 2"); + unitFailed("h.get(\"Number 2\") should have thrown an exception."); + } catch( Bu::HashException &e ) { } + + printf("\n"); + for( StrIntHash::iterator i = h.begin(); i != h.end(); i++ ) + { + printf(" - \"%s\" = %d\n", i.getKey().getStr(), i.getValue() ); + } + } }; int main( int argc, char *argv[] ) -- cgit v1.2.3