#include "bu/myriadcache.h" #include "bu/uuid.h" #include "bu/string.h" #include "bu/sio.h" class Something : public Bu::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 Bu::Uuid getKey() const { return uId; } Bu::String getName() const { return sName; } void setName( const Bu::String &sNewName ) { sName = sNewName; changed(); } virtual Bu::String toString() const=0; private: Bu::Uuid uId; Bu::String sName; }; class SubSomethingA : public Something { friend Bu::ArchiveBase &operator>>( Bu::ArchiveBase &ar, SubSomethingA &s ); friend Bu::ArchiveBase &operator<<( Bu::ArchiveBase &ar, const SubSomethingA &s ); public: SubSomethingA() { } SubSomethingA( const Bu::String &sName, int iNumber ) : Something( sName ), iNumber( iNumber ) { } virtual Bu::String toString() const { return Bu::String("[typeA] %1 (%2)").arg( getName() ).arg( iNumber ); } private: int iNumber; }; class SubSomethingB : public Something { friend Bu::ArchiveBase &operator>>( Bu::ArchiveBase &ar, SubSomethingB &s ); friend Bu::ArchiveBase &operator<<( Bu::ArchiveBase &ar, const SubSomethingB &s ); public: SubSomethingB() { } SubSomethingB( const Bu::String &sName, const Bu::String &sString ) : Something( sName ), sString( sString ) { } virtual Bu::String toString() const { return Bu::String("[typeB] %1 (%2)").arg( getName() ).arg( sString ); } private: Bu::String sString; }; 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; } Bu::ArchiveBase &operator>>( Bu::ArchiveBase &ar, SubSomethingA &s ) { return ar >> (Something &)s >> s.iNumber; } Bu::ArchiveBase &operator<<( Bu::ArchiveBase &ar, const SubSomethingA &s ) { return ar << (Something &)s << s.iNumber; } Bu::ArchiveBase &operator>>( Bu::ArchiveBase &ar, SubSomethingB &s ) { return ar >> (Something &)s >> s.sString; } Bu::ArchiveBase &operator<<( Bu::ArchiveBase &ar, const SubSomethingB &s ) { return ar << (Something &)s << s.sString; } namespace Bu { template<> void _cacheObjectSave( Bu::Stream &s, const Something *pObject ) { Bu::Archive ar( s, Bu::Archive::save ); if( typeid(*pObject) == typeid(SubSomethingA) ) { ar << (uint8_t)1 << (SubSomethingA &)*pObject; } else if( typeid(*pObject) == typeid(SubSomethingB) ) { ar << (uint8_t)2 << (SubSomethingB &)*pObject; } else { Bu::println("Not a recognized type!"); throw Bu::ExceptionBase("Not recognized type!"); } } template<> Something *_cacheObjectLoad( Bu::CacheObject::Initializer &initObj, const Bu::Uuid &rKey, Bu::Stream &s ) { Bu::Archive ar( s, Bu::Archive::load ); uint8_t uType; ar >> uType; switch( uType ) { case 1: { SubSomethingA *ret = initObj(new SubSomethingA()); ar >> *ret; return ret; } break; case 2: { SubSomethingB *ret = initObj(new SubSomethingB()); ar >> *ret; return ret; } break; default: throw Bu::ExceptionBase("Flagrant error! Invalid type!"); } return NULL; } } typedef Bu::CachePtr SomethingPtr; typedef Bu::CachePtr SomethingAPtr; typedef Bu::CachePtr SomethingBPtr; typedef Bu::MyriadCache SomethingCache; int main( int, char *[] ) { Bu::File fStore("test.myr", Bu::File::Create|Bu::File::ReadWrite); SomethingCache c( fStore ); SomethingPtr ptr; if( time(NULL)%2 ) ptr = c.insert( new SubSomethingA("Hello", 55) ).cast(); else ptr = c.insert( new SubSomethingB("Goodbye", "Things") ).cast(); Bu::println("Something[%1]: %2"). arg( ptr.getKey() ). arg( ptr->getName() ); SomethingCache::KeyList lKeys = c.getKeys(); Bu::println("Count: %1").arg( lKeys.getSize() ); for( SomethingCache::KeyList::iterator i = lKeys.begin(); i; i++ ) { Bu::println(" - %1: '%2'").arg( *i ).arg( c.get( *i )->toString() ); } Bu::println("Count: %1").arg( c.getSize() ); SomethingPtr p2 = c.get( ptr.getKey() ); Bu::println("%1 == %2").arg( p2->getName() ).arg( ptr->getName() ); SomethingPtr p3 = ptr.cast(); Bu::println("%1: %2").arg( p3.getKey() ).arg( p3->getName() ); return 0; } /* int main( int argc, char *argv[] ) { Bu::File fStore("test.myr", Bu::File::Create|Bu::File::ReadWrite); SomethingCache c( fStore ); for( int j = 1; j < argc; j++ ) { SomethingPtr ptr = c.insert( new Something(argv[j]) ); Bu::println("Something[%1]: %2"). arg( ptr.getKey() ). arg( ptr->getName() ); } SomethingCache::KeyList lKeys = c.getKeys(); Bu::println("Count: %1").arg( lKeys.getSize() ); int j = 0; for( SomethingCache::KeyList::iterator i = lKeys.begin(); i; i++ ) { Bu::println(" - %1: '%2'").arg( *i ).arg( c.get( *i )->getName() ); if( ((j++)%2) ) c.erase( *i ); } Bu::println("Count: %1").arg( c.getSize() ); c._debug(); SomethingPtr p2; SomethingPtr p1( c.get( lKeys.first() ) ); c._debug(); { SomethingPtr p2( p1 ); c._debug(); } c._debug(); p2 = p1; c._debug(); p1.unbind(); c._debug(); Bu::println("Name: %1").arg( p1->getName() ); p1.unbind(); p1.lock(); p1.unlock(); c._debug(); SomethingPtr p3 = c.getLazy( lKeys.first() ); c._debug(); { SomethingPtr::Locker l( p3 ); Bu::println("Name again: %1").arg( p3->getName() ); p3->setName( p3->getName() + " - again" ); } c.sync(); c._debug(); return 0; } */