From 21a4337dc2f969dc3ec81e6ba3170119bcb67016 Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Tue, 22 Jul 2014 16:39:01 +0000 Subject: Deferred erase now works on cache entries. You can erase a cache entry while it still has active references, and it will be safely cleaned up when the last reference is released. --- src/tests/cachedel.cpp | 288 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 288 insertions(+) create mode 100644 src/tests/cachedel.cpp (limited to 'src/tests') diff --git a/src/tests/cachedel.cpp b/src/tests/cachedel.cpp new file mode 100644 index 0000000..817757c --- /dev/null +++ b/src/tests/cachedel.cpp @@ -0,0 +1,288 @@ +#include "bu/myriadcache.h" +#include "bu/uuid.h" +#include "bu/string.h" +#include "bu/sio.h" +#include "bu/membuf.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::MemBuf mbStore; + SomethingCache c( mbStore ); + + SomethingPtr ptr; + if( time(NULL)%2 ) + ptr = c.insert( new SubSomethingA("Hello", 55) ).cast(); + else + ptr = c.insert( new SubSomethingB("Goodbye", "Things") ).cast(); + + Bu::Uuid id = ptr.getKey(); + Bu::println("Something[%1]: %2"). + arg( ptr.getKey() ). + arg( ptr->getName() ); + + Bu::println("has %1: %2").arg( id ).arg( c.has( id ) ); + c.erase( ptr.getKey() ); + Bu::println("has %1: %2").arg( id ).arg( c.has( id ) ); + SomethingPtr b = ptr; + + SomethingPtr p2 = c.insert( new SubSomethingA("new test", 123) ).cast(); + id = p2.getKey(); + p2.unbind(); + c.erase( id ); + + 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; +} +*/ -- cgit v1.2.3