/* * Copyright (C) 2007-2023 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.open( 1, Bu::Myriad::WriteNew|Bu::Myriad::Read ); Bu::Archive ar( ms, Bu::Archive::load ); uint8_t uVer; ar >> uVer; switch( uVer ) { case 0: ar >> hIndex; break; } } catch(...) { try { mStore.open( 1, Bu::Myriad::Create|Bu::Myriad::ReadWrite ); _sync(); } catch(...) { throw Bu::ExceptionBase("Error creating index stream."); } } } virtual ~MyriadCache() { Bu::CacheBase::sync(); } using typename Bu::CacheBase::KeyList; using typename Bu::CacheBase::ObjectType; 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 ); { Bu::Myriad::StreamId id = mStore.allocate(); hIndex.insert( o->getKey(), id ); } _save( o ); bStructureChanged = true; } virtual void _erase( const keytype &k ) { Bu::ReadWriteMutex::WriteLocker wl( rwStore ); mStore.erase( hIndex.get( k ) ); hIndex.erase( k ); bStructureChanged = true; } virtual obtype *_load( typename Bu::CacheObject::Initializer &initObj, const keytype &k ) { Bu::MyriadStream ms = mStore.openStream( hIndex.get( k ) ); return _cacheObjectLoad( initObj, k, ms ); } virtual void _save( const obtype *o ) { Bu::MyriadStream ms = mStore.openStream( hIndex.get( o->getKey() ) ); _cacheObjectSave( ms, o ); ms.setSize( ms.tell() ); mStore.sync(); } virtual void _sync() { Bu::ReadWriteMutex::WriteLocker 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; mStore.sync(); } private: Bu::Stream &sStore; Bu::Myriad mStore; Bu::Hash hIndex; mutable Bu::ReadWriteMutex rwStore; bool bStructureChanged; }; } #endif