/* * Copyright (C) 2007-2013 Xagasoft, All rights reserved. * * This file is part of the libbu++ library and is released under the * terms of the license contained in the file LICENSE. */ #ifndef BU_MYRIAD_CACHE_H #define BU_MYRIAD_CACHE_H #include "bu/cachebase.h" #include "bu/myriad.h" #include "bu/myriadstream.h" #include "bu/file.h" #include "bu/streamstack.h" namespace Bu { template class MyriadCache : public Bu::CacheBase { public: MyriadCache( Bu::Stream &sStore, int iBlockSize=512, int iPreallocate=8 ) : sStore( sStore ), mStore( sStore, iBlockSize, iPreallocate ), bStructureChanged( false ) { try { Bu::ReadWriteMutex::ReadLocker l( rwStore ); Bu::MyriadStream ms = mStore.openStream( 1 ); Bu::Archive ar( ms, Bu::Archive::load ); uint8_t uVer; ar >> uVer; switch( uVer ) { case 0: ar >> hIndex; break; } } catch(...) { if( mStore.createStreamWithId( 1 ) != 1 ) throw Bu::ExceptionBase("Error creating index stream."); _sync(); } } virtual ~MyriadCache() { _sync(); } using typename Bu::CacheBase::KeyList; virtual typename Bu::CacheBase::KeyList getKeys() const { Bu::ReadWriteMutex::ReadLocker rl( rwStore ); return hIndex.getKeys(); } virtual int getSize() const { Bu::ReadWriteMutex::ReadLocker rl( rwStore ); return hIndex.getSize(); } protected: virtual bool _has( const keytype &key ) { Bu::ReadWriteMutex::ReadLocker rl( rwStore ); return hIndex.has( key ); } virtual void _create( const obtype *o ) { Bu::ReadWriteMutex::WriteLocker wl( rwStore ); hIndex.insert( o->getKey(), mStore.createStream() ); _save( o ); bStructureChanged = true; } virtual void _erase( const keytype &k ) { Bu::ReadWriteMutex::WriteLocker wl( rwStore ); mStore.deleteStream( hIndex.get( k ) ); hIndex.erase( k ); bStructureChanged = true; } virtual obtype *_load( const keytype &k ) { Bu::MyriadStream ms = mStore.openStream( hIndex.get( k ) ); return _cacheObjectLoad( ms ); } virtual void _save( const obtype *o ) { Bu::MyriadStream ms = mStore.openStream( hIndex.get( o->getKey() ) ); _cacheObjectSave( ms, o ); ms.setSize( ms.tell() ); } virtual void _sync() { Bu::ReadWriteMutex::ReadLocker wl( rwStore ); if( !bStructureChanged ) return; Bu::MyriadStream ms = mStore.openStream( 1 ); Bu::Archive ar( ms, Bu::Archive::save ); ar << (uint8_t)0 << hIndex; ar.close(); ms.setSize( ms.tell() ); bStructureChanged = false; } private: Bu::Stream &sStore; Bu::Myriad mStore; Bu::Hash hIndex; mutable Bu::ReadWriteMutex rwStore; bool bStructureChanged; }; } #endif