#include #include #include #include #include #include #include // // New Cache Implementation // template class CacheBase; template class CacheObject { friend class CacheBase; public: CacheObject() : pCache( NULL ), bChanged( false ) { } virtual ~CacheObject() { } typedef CacheBase CacheType; virtual const keytype getKey() const=0; void changed( bool bChanged=true ) { if( this->bChanged == false && bChanged == true ) pCache->objectChanged( getKey() ); this->bChanged = bChanged; } private: void setCache( CacheType *pCache ) { this->pCache = pCache; } private: CacheType *pCache; bool bChanged; }; template class CachePtr { friend class CacheBase; public: CachePtr() { } virtual ~CachePtr() { } }; template class CacheBase { public: CacheBase() { } virtual ~CacheBase() { } protected: virtual void _create( obtype *o )=0; virtual void _erase( const keytype &k )=0; virtual obtype *_load( const keytype &k )=0; virtual void _save( obtype *o )=0; }; template class MyriadCache : public CacheBase { public: MyriadCache( Bu::Stream &sStore, int iBlockSize=512, int iPreallocate=8 ) : sStore( sStore ), mStore( sStore, iBlockSize, iPreallocate ) { try { Bu::MyriadStream ms = mStore.openStream( 1 ); Bu::Archive ar( ms, Bu::Archive::load ); ar >> hIndex; } catch(...) { if( mStore.createStreamWithId( 1 ) != 1 ) throw Bu::ExceptionBase("Error creating index stream."); Bu::MyriadStream ms = mStore.openStream( 1 ); Bu::Archive ar( ms, Bu::Archive::save ); ar << hIndex; } } virtual ~MyriadCache() { } protected: virtual void _create( obtype *o ) { hIndex.insert( o->getKey(), mStore.createStream() ); _save( o ); } virtual void _erase( const keytype &k ) { mStore.deleteStream( hIndex.get( k ) ); hIndex.erase( k ); } virtual obtype *_load( const keytype &k ) { Bu::MyriadStream ms = mStore.openStream( hIndex.get( k ) ); Bu::Archive ar( ms, Bu::Archive::load ); obtype *ret = new obtype(); ar >> *ret; return ret; } virtual void _save( obtype *o ) { Bu::MyriadStream ms = mStore.openStream( hIndex.get( o->getKey() ) ); { Bu::Archive ar( ms, Bu::Archive::save ); ar << *o; } ms.setSize( ms.tell() ); } private: Bu::Stream &sStore; Bu::Myriad mStore; Bu::Hash hIndex; }; // // Test // class Something : public CacheObject { friend Bu::ArchiveBase &operator>>( Bu::ArchiveBase &ar, Something &s ); friend Bu::ArchiveBase &operator<<( Bu::ArchiveBase &ar, const Something &s ); public: Something() { } Something( const Bu::String &sName ) : uId( Bu::Uuid::generate() ), sName( sName ) { } virtual ~Something() { } virtual const Bu::Uuid getKey() const { return uId; } private: Bu::Uuid uId; Bu::String sName; }; Bu::ArchiveBase &operator>>( Bu::ArchiveBase &ar, Something &s ) { return ar >> s.uId >> s.sName; } Bu::ArchiveBase &operator<<( Bu::ArchiveBase &ar, const Something &s ) { return ar << s.uId << s.sName; } int main() { Bu::File fStore("test.myr", Bu::File::Create|Bu::File::ReadWrite); MyriadCache c( fStore ); return 0; }