diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/tests/cache.cpp | 419 |
1 files changed, 335 insertions, 84 deletions
diff --git a/src/tests/cache.cpp b/src/tests/cache.cpp index 6fc4e4a..15662af 100644 --- a/src/tests/cache.cpp +++ b/src/tests/cache.cpp | |||
| @@ -55,22 +55,148 @@ private: | |||
| 55 | bool bChanged; | 55 | bool bChanged; |
| 56 | }; | 56 | }; |
| 57 | 57 | ||
| 58 | template<typename keytype, typename obtype> | ||
| 59 | class CacheBase; | ||
| 60 | |||
| 61 | template<typename keytype, typename obtype> | ||
| 62 | class CacheEntry | ||
| 63 | { | ||
| 64 | friend class CacheBase<keytype, obtype>; | ||
| 65 | private: | ||
| 66 | CacheEntry( obtype *pObject ) : | ||
| 67 | iRefCount( 0 ), | ||
| 68 | pObject( pObject ) | ||
| 69 | { | ||
| 70 | } | ||
| 71 | |||
| 72 | public: | ||
| 73 | int getRefCount() const | ||
| 74 | { | ||
| 75 | mEntry.lock(); | ||
| 76 | int ret = iRefCount; | ||
| 77 | mEntry.unlock(); | ||
| 78 | return ret; | ||
| 79 | } | ||
| 80 | |||
| 81 | obtype *getPtr() const | ||
| 82 | { | ||
| 83 | return pObject; | ||
| 84 | } | ||
| 85 | |||
| 86 | void lock() const | ||
| 87 | { | ||
| 88 | mObject.lock(); | ||
| 89 | } | ||
| 90 | |||
| 91 | void unlock() const | ||
| 92 | { | ||
| 93 | mObject.unlock(); | ||
| 94 | } | ||
| 95 | |||
| 96 | void incRef() | ||
| 97 | { | ||
| 98 | mEntry.lock(); | ||
| 99 | iRefCount++; | ||
| 100 | mEntry.unlock(); | ||
| 101 | } | ||
| 102 | |||
| 103 | bool decRef() | ||
| 104 | { | ||
| 105 | mEntry.lock(); | ||
| 106 | iRefCount--; | ||
| 107 | bool bRet = iRefCount > 0; | ||
| 108 | mEntry.unlock(); | ||
| 109 | return bRet; | ||
| 110 | } | ||
| 111 | |||
| 112 | private: | ||
| 113 | mutable Bu::Mutex mEntry; | ||
| 114 | mutable Bu::Mutex mObject; | ||
| 115 | int iRefCount; | ||
| 116 | obtype *pObject; | ||
| 117 | }; | ||
| 118 | |||
| 119 | template<typename keytype, typename basetype> | ||
| 120 | class CachePtrInterface | ||
| 121 | { | ||
| 122 | protected: | ||
| 123 | CachePtrInterface() | ||
| 124 | { | ||
| 125 | } | ||
| 126 | |||
| 127 | virtual ~CachePtrInterface() | ||
| 128 | { | ||
| 129 | } | ||
| 130 | |||
| 131 | template<typename obtype> | ||
| 132 | void checkRef( CacheBase<keytype, basetype> *pCache, | ||
| 133 | const keytype &kId, | ||
| 134 | CacheEntry<keytype, basetype> * &rpEnt, | ||
| 135 | obtype * &rpData ) | ||
| 136 | { | ||
| 137 | if( pCache == NULL ) | ||
| 138 | throw Bu::ExceptionBase("Invalid pointer"); | ||
| 139 | |||
| 140 | if( !rpData ) | ||
| 141 | { | ||
| 142 | rpEnt = pCache->getRef( kId ); | ||
| 143 | rpEnt->incRef(); | ||
| 144 | rpData = dynamic_cast<obtype *>(rpEnt->getPtr()); | ||
| 145 | if( rpData == NULL ) | ||
| 146 | { | ||
| 147 | rpEnt->decRef(); | ||
| 148 | rpEnt = NULL; | ||
| 149 | throw std::bad_cast(); | ||
| 150 | } | ||
| 151 | } | ||
| 152 | } | ||
| 153 | |||
| 154 | template<typename obtype> | ||
| 155 | void releaseRef( CacheBase<keytype, basetype> *pCache, | ||
| 156 | CacheEntry<keytype, basetype> * &rpEnt, | ||
| 157 | obtype * &rpData ) | ||
| 158 | { | ||
| 159 | if( pCache == NULL ) | ||
| 160 | return; | ||
| 161 | |||
| 162 | if( rpData == NULL ) | ||
| 163 | return; | ||
| 164 | |||
| 165 | rpData = NULL; | ||
| 166 | rpEnt->decRef(); | ||
| 167 | pCache->releaseRef( rpEnt ); | ||
| 168 | rpEnt = NULL; | ||
| 169 | } | ||
| 170 | }; | ||
| 171 | |||
| 58 | template<typename keytype, typename obtype, typename basetype=obtype> | 172 | template<typename keytype, typename obtype, typename basetype=obtype> |
| 59 | class CachePtr | 173 | class CachePtr : protected CachePtrInterface<keytype, basetype> |
| 60 | { | 174 | { |
| 61 | friend class CacheBase<keytype, basetype>; | 175 | friend class CacheBase<keytype, basetype>; |
| 62 | private: | 176 | private: |
| 63 | CachePtr( CacheBase<keytype, basetype> *pCache, obtype *pData, | 177 | typedef CachePtr<keytype, obtype, basetype> MyType; |
| 178 | |||
| 179 | CachePtr( CacheBase<keytype, basetype> *pCache, | ||
| 180 | CacheEntry<keytype, basetype> *pEnt, | ||
| 64 | const keytype &kId ) : | 181 | const keytype &kId ) : |
| 65 | pCache( pCache ), | 182 | pCache( pCache ), |
| 66 | kId( kId ), | 183 | kId( kId ), |
| 67 | pData( pData ) | 184 | pEnt( pEnt ), |
| 185 | pData( NULL ) | ||
| 68 | { | 186 | { |
| 187 | pEnt->incRef(); | ||
| 188 | pData = dynamic_cast<obtype *>( pEnt->getPtr() ); | ||
| 189 | if( pData == NULL ) | ||
| 190 | { | ||
| 191 | pEnt->decRef(); | ||
| 192 | throw std::bad_cast(); | ||
| 193 | } | ||
| 69 | } | 194 | } |
| 70 | 195 | ||
| 71 | CachePtr( CacheBase<keytype, basetype> *pCache, const keytype &kId ) : | 196 | CachePtr( CacheBase<keytype, basetype> *pCache, const keytype &kId ) : |
| 72 | pCache( pCache ), | 197 | pCache( pCache ), |
| 73 | kId( kId ), | 198 | kId( kId ), |
| 199 | pEnt( NULL ), | ||
| 74 | pData( NULL ) | 200 | pData( NULL ) |
| 75 | { | 201 | { |
| 76 | } | 202 | } |
| @@ -78,12 +204,23 @@ private: | |||
| 78 | public: | 204 | public: |
| 79 | CachePtr() : | 205 | CachePtr() : |
| 80 | pCache( NULL ), | 206 | pCache( NULL ), |
| 207 | pEnt( NULL ), | ||
| 81 | pData( NULL ) | 208 | pData( NULL ) |
| 82 | { | 209 | { |
| 83 | } | 210 | } |
| 84 | 211 | ||
| 212 | CachePtr( const MyType &rhs ) : | ||
| 213 | pCache( rhs.pCache ), | ||
| 214 | kId( rhs.kId ), | ||
| 215 | pEnt( rhs.pEnt ), | ||
| 216 | pData( rhs.pData ) | ||
| 217 | { | ||
| 218 | pEnt->incRef(); | ||
| 219 | } | ||
| 220 | |||
| 85 | virtual ~CachePtr() | 221 | virtual ~CachePtr() |
| 86 | { | 222 | { |
| 223 | release(); | ||
| 87 | } | 224 | } |
| 88 | 225 | ||
| 89 | const keytype &getKey() const | 226 | const keytype &getKey() const |
| @@ -96,34 +233,113 @@ public: | |||
| 96 | checkRef(); | 233 | checkRef(); |
| 97 | return pData; | 234 | return pData; |
| 98 | } | 235 | } |
| 236 | |||
| 237 | const obtype &operator*() const | ||
| 238 | { | ||
| 239 | checkRef(); | ||
| 240 | return pData; | ||
| 241 | } | ||
| 99 | 242 | ||
| 100 | obtype *operator->() | 243 | obtype *operator->() |
| 101 | { | 244 | { |
| 102 | checkRef(); | 245 | checkRef(); |
| 103 | return pData; | 246 | return pData; |
| 104 | } | 247 | } |
| 248 | |||
| 249 | const obtype *operator->() const | ||
| 250 | { | ||
| 251 | checkRef(); | ||
| 252 | return pData; | ||
| 253 | } | ||
| 254 | |||
| 255 | MyType operator=( const MyType &rhs ) | ||
| 256 | { | ||
| 257 | release(); | ||
| 258 | pCache = rhs.pCache; | ||
| 259 | kId = rhs.kId; | ||
| 260 | pEnt = rhs.pEnt; | ||
| 261 | pData = rhs.pData; | ||
| 262 | pEnt->incRef(); | ||
| 263 | |||
| 264 | return *this; | ||
| 265 | } | ||
| 266 | |||
| 267 | bool operator==( const MyType &rhs ) const | ||
| 268 | { | ||
| 269 | return pCache == rhs.pCache && | ||
| 270 | kId == rhs.kId; | ||
| 271 | } | ||
| 272 | |||
| 273 | bool operator!=( const MyType &rhs ) const | ||
| 274 | { | ||
| 275 | return pCache != rhs.pCache || | ||
| 276 | kId != rhs.kId; | ||
| 277 | } | ||
| 278 | |||
| 279 | void release() | ||
| 280 | { | ||
| 281 | CachePtrInterface<keytype, basetype>::releaseRef( pCache, pEnt, pData ); | ||
| 282 | } | ||
| 283 | |||
| 284 | void lock() | ||
| 285 | { | ||
| 286 | checkRef(); | ||
| 287 | if( pEnt ) | ||
| 288 | pEnt->lock(); | ||
| 289 | } | ||
| 290 | |||
| 291 | void unlock() | ||
| 292 | { | ||
| 293 | checkRef(); | ||
| 294 | if( pEnt ) | ||
| 295 | pEnt->unlock(); | ||
| 296 | } | ||
| 297 | |||
| 298 | class Locker | ||
| 299 | { | ||
| 300 | public: | ||
| 301 | Locker( MyType &rPtr ) : | ||
| 302 | rPtr( rPtr ), | ||
| 303 | bLocked( true ) | ||
| 304 | { | ||
| 305 | rPtr.lock(); | ||
| 306 | } | ||
| 307 | |||
| 308 | ~Locker() | ||
| 309 | { | ||
| 310 | unlock(); | ||
| 311 | } | ||
| 312 | |||
| 313 | void unlock() | ||
| 314 | { | ||
| 315 | if( !bLocked ) | ||
| 316 | return; | ||
| 317 | rPtr.unlock(); | ||
| 318 | bLocked = false; | ||
| 319 | } | ||
| 320 | |||
| 321 | private: | ||
| 322 | MyType &rPtr; | ||
| 323 | bool bLocked; | ||
| 324 | }; | ||
| 105 | 325 | ||
| 106 | private: | 326 | private: |
| 107 | void checkRef() | 327 | void checkRef() |
| 108 | { | 328 | { |
| 109 | if( pCache == NULL ) | 329 | CachePtrInterface<keytype, basetype>::checkRef( pCache, kId, pEnt, pData ); |
| 110 | throw Bu::ExceptionBase("Invalid pointer"); | ||
| 111 | |||
| 112 | if( !pData ) | ||
| 113 | pData = pCache->getRef( kId ); | ||
| 114 | } | 330 | } |
| 115 | 331 | ||
| 116 | private: | 332 | private: |
| 117 | CacheBase<keytype, basetype> *pCache; | 333 | CacheBase<keytype, basetype> *pCache; |
| 118 | mutable keytype kId; | 334 | mutable keytype kId; |
| 335 | mutable CacheEntry<keytype, basetype> *pEnt; | ||
| 119 | mutable obtype *pData; | 336 | mutable obtype *pData; |
| 120 | |||
| 121 | }; | 337 | }; |
| 122 | 338 | ||
| 123 | template<typename keytype, typename obtype> | 339 | template<typename keytype, typename obtype> |
| 124 | class CacheBase | 340 | class CacheBase |
| 125 | { | 341 | { |
| 126 | friend class CachePtr<keytype, obtype>; | 342 | friend class CachePtrInterface<keytype, obtype>; |
| 127 | public: | 343 | public: |
| 128 | CacheBase() | 344 | CacheBase() |
| 129 | { | 345 | { |
| @@ -133,14 +349,17 @@ public: | |||
| 133 | { | 349 | { |
| 134 | } | 350 | } |
| 135 | 351 | ||
| 352 | typedef CacheEntry<keytype, obtype> Entry; | ||
| 136 | typedef Bu::List<keytype> KeyList; | 353 | typedef Bu::List<keytype> KeyList; |
| 137 | 354 | ||
| 355 | |||
| 138 | CachePtr<keytype, obtype> insert( const obtype *pObject ) | 356 | CachePtr<keytype, obtype> insert( const obtype *pObject ) |
| 139 | { | 357 | { |
| 140 | CacheEntry *pEnt = addEntry( pObject ); | 358 | Entry *pEnt = addEntry( pObject ); |
| 141 | 359 | ||
| 142 | pEnt->incRef(); | 360 | return CachePtr<keytype, obtype>( |
| 143 | return CachePtr<keytype, obtype>( this, pEnt->getPtr(), pObject->getKey() ); | 361 | this, pEnt, pObject->getKey() |
| 362 | ); | ||
| 144 | } | 363 | } |
| 145 | 364 | ||
| 146 | template<typename supertype> | 365 | template<typename supertype> |
| @@ -150,84 +369,68 @@ public: | |||
| 150 | if( pCast == NULL ) | 369 | if( pCast == NULL ) |
| 151 | throw std::bad_cast(); | 370 | throw std::bad_cast(); |
| 152 | 371 | ||
| 153 | CacheEntry *pEnt = addEntry( pCast ); | 372 | Entry *pEnt = addEntry( pCast ); |
| 154 | 373 | ||
| 155 | pEnt->incRef(); | 374 | return CachePtr<keytype, supertype, obtype>( |
| 156 | return CachePtr<keytype, supertype, obtype>( this, pObject, pObject->getKey() ); | 375 | this, pEnt, pObject->getKey() |
| 376 | ); | ||
| 157 | } | 377 | } |
| 158 | 378 | ||
| 159 | CachePtr<keytype, obtype> get( const keytype &key ) | 379 | CachePtr<keytype, obtype> get( const keytype &key ) |
| 160 | { | 380 | { |
| 161 | CacheEntry *pEnt = getEntry( key ); | 381 | Entry *pEnt = getEntry( key ); |
| 162 | pEnt->incRef(); | 382 | return CachePtr<keytype, obtype>( this, pEnt, key ); |
| 163 | return CachePtr<keytype, obtype>( this, pEnt->getPtr(), key ); | ||
| 164 | } | 383 | } |
| 165 | 384 | ||
| 166 | template<typename supertype> | 385 | template<typename supertype> |
| 167 | CachePtr<keytype, supertype, obtype> get( const keytype &key ) | 386 | CachePtr<keytype, supertype, obtype> get( const keytype &key ) |
| 168 | { | 387 | { |
| 169 | CacheEntry *pEnt = getEntry( key ); | 388 | Entry *pEnt = getEntry( key ); |
| 170 | pEnt->incRef(); | 389 | return CachePtr<keytype, supertype, obtype>( this, pEnt, key ); |
| 171 | supertype *pCast = dynamic_cast<supertype *>( pEnt->getPtr() ); | ||
| 172 | if( pCast == NULL ) | ||
| 173 | { | ||
| 174 | pEnt->decRef(); | ||
| 175 | throw std::bad_cast(); | ||
| 176 | } | ||
| 177 | return CachePtr<keytype, supertype, obtype>( this, pCast, key ); | ||
| 178 | } | 390 | } |
| 179 | 391 | ||
| 180 | virtual KeyList getKeys() const=0; | 392 | CachePtr<keytype, obtype> getLazy( const keytype &key ) |
| 181 | |||
| 182 | virtual void sync()=0; | ||
| 183 | |||
| 184 | protected: | ||
| 185 | obtype *getRef( const keytype &k ) | ||
| 186 | { | 393 | { |
| 187 | CacheEntry *pEnt = getEntry( k ); | 394 | return CachePtr<keytype, obtype>( this, key ); |
| 188 | pEnt->incRef(); | ||
| 189 | return pEnt->getPtr(); | ||
| 190 | } | 395 | } |
| 191 | 396 | ||
| 192 | void objectChanged( const keytype &k ) | 397 | template<typename supertype> |
| 398 | CachePtr<keytype, supertype, obtype> getLazy( const keytype &key ) | ||
| 193 | { | 399 | { |
| 400 | return CachePtr<keytype, supertype, obtype>( this, key ); | ||
| 194 | } | 401 | } |
| 195 | 402 | ||
| 196 | class CacheEntry | 403 | virtual KeyList getKeys() const=0; |
| 404 | |||
| 405 | virtual void sync()=0; | ||
| 406 | |||
| 407 | void _debug() | ||
| 197 | { | 408 | { |
| 198 | public: | 409 | Bu::ReadWriteMutex::ReadLocker rl( mCacheEntry ); |
| 199 | CacheEntry( obtype *pObject ) : | 410 | Bu::println("Cache entries:"); |
| 200 | iRefCount( 0 ), | 411 | for( typename CacheEntryHash::iterator i = hCacheEntry.begin(); i; i++ ) |
| 201 | pObject( pObject ) | ||
| 202 | { | 412 | { |
| 413 | Bu::println(" %1: refs=%2"). | ||
| 414 | arg( i.getKey() ). | ||
| 415 | arg( i.getValue()->getRefCount() ); | ||
| 203 | } | 416 | } |
| 417 | } | ||
| 204 | 418 | ||
| 205 | void incRef() | 419 | protected: |
| 206 | { | 420 | Entry *getRef( const keytype &k ) |
| 207 | mEntry.lock(); | 421 | { |
| 208 | iRefCount++; | 422 | Entry *pEnt = getEntry( k ); |
| 209 | mEntry.unlock(); | 423 | return pEnt; |
| 210 | } | 424 | } |
| 211 | 425 | ||
| 212 | bool decRef() | 426 | void releaseRef( Entry * )//pEnt ) |
| 213 | { | 427 | { |
| 214 | mEntry.lock(); | 428 | } |
| 215 | iRefCount--; | ||
| 216 | bool bRet = iRefCount > 0; | ||
| 217 | mEntry.unlock(); | ||
| 218 | return bRet; | ||
| 219 | } | ||
| 220 | 429 | ||
| 221 | obtype *getPtr() | 430 | void objectChanged( const keytype &k ) |
| 222 | { | 431 | { |
| 223 | return pObject; | 432 | } |
| 224 | } | ||
| 225 | 433 | ||
| 226 | private: | ||
| 227 | Bu::Mutex mEntry; | ||
| 228 | int iRefCount; | ||
| 229 | obtype *pObject; | ||
| 230 | }; | ||
| 231 | 434 | ||
| 232 | protected: | 435 | protected: |
| 233 | virtual void _create( const obtype *o )=0; | 436 | virtual void _create( const obtype *o )=0; |
| @@ -237,9 +440,9 @@ protected: | |||
| 237 | virtual void _save( const obtype *o )=0; | 440 | virtual void _save( const obtype *o )=0; |
| 238 | 441 | ||
| 239 | private: | 442 | private: |
| 240 | CacheEntry *addEntry( const obtype *pObject ) | 443 | Entry *addEntry( const obtype *pObject ) |
| 241 | { | 444 | { |
| 242 | CacheEntry *pEnt = new CacheEntry( const_cast<obtype *>(pObject) ); | 445 | Entry *pEnt = new Entry( const_cast<obtype *>(pObject) ); |
| 243 | mCacheEntry.lockWrite(); | 446 | mCacheEntry.lockWrite(); |
| 244 | hCacheEntry.insert( pObject->getKey(), pEnt ); | 447 | hCacheEntry.insert( pObject->getKey(), pEnt ); |
| 245 | mCacheEntry.unlockWrite(); | 448 | mCacheEntry.unlockWrite(); |
| @@ -248,9 +451,9 @@ private: | |||
| 248 | return pEnt; | 451 | return pEnt; |
| 249 | } | 452 | } |
| 250 | 453 | ||
| 251 | CacheEntry *getEntry( const keytype &k ) | 454 | Entry *getEntry( const keytype &k ) |
| 252 | { | 455 | { |
| 253 | CacheEntry *pEnt = NULL; | 456 | Entry *pEnt = NULL; |
| 254 | try | 457 | try |
| 255 | { | 458 | { |
| 256 | Bu::ReadWriteMutex::ReadLocker rl( mCacheEntry ); | 459 | Bu::ReadWriteMutex::ReadLocker rl( mCacheEntry ); |
| @@ -260,7 +463,7 @@ private: | |||
| 260 | { | 463 | { |
| 261 | // try to load the object from the backing store | 464 | // try to load the object from the backing store |
| 262 | obtype *pObject = _load( k ); | 465 | obtype *pObject = _load( k ); |
| 263 | pEnt = new CacheEntry( pObject ); | 466 | pEnt = new Entry( pObject ); |
| 264 | Bu::ReadWriteMutex::WriteLocker wl( mCacheEntry ); | 467 | Bu::ReadWriteMutex::WriteLocker wl( mCacheEntry ); |
| 265 | hCacheEntry.insert( k, pEnt ); | 468 | hCacheEntry.insert( k, pEnt ); |
| 266 | } | 469 | } |
| @@ -268,10 +471,9 @@ private: | |||
| 268 | } | 471 | } |
| 269 | 472 | ||
| 270 | private: | 473 | private: |
| 271 | typedef Bu::Hash<keytype, CacheEntry *> CacheEntryHash; | 474 | typedef Bu::Hash<keytype, Entry *> CacheEntryHash; |
| 272 | CacheEntryHash hCacheEntry; | 475 | CacheEntryHash hCacheEntry; |
| 273 | Bu::ReadWriteMutex mCacheEntry; | 476 | Bu::ReadWriteMutex mCacheEntry; |
| 274 | |||
| 275 | }; | 477 | }; |
| 276 | 478 | ||
| 277 | template<typename keytype, typename obtype> | 479 | template<typename keytype, typename obtype> |
| @@ -282,21 +484,26 @@ public: | |||
| 282 | sStore( sStore ), | 484 | sStore( sStore ), |
| 283 | mStore( sStore, iBlockSize, iPreallocate ) | 485 | mStore( sStore, iBlockSize, iPreallocate ) |
| 284 | { | 486 | { |
| 285 | Bu::ReadWriteMutex::WriteLocker wl( rwStore ); | ||
| 286 | try | 487 | try |
| 287 | { | 488 | { |
| 489 | Bu::ReadWriteMutex::ReadLocker l( rwStore ); | ||
| 288 | Bu::MyriadStream ms = mStore.openStream( 1 ); | 490 | Bu::MyriadStream ms = mStore.openStream( 1 ); |
| 289 | Bu::Archive ar( ms, Bu::Archive::load ); | 491 | Bu::Archive ar( ms, Bu::Archive::load ); |
| 290 | ar >> hIndex; | 492 | uint8_t uVer; |
| 493 | ar >> uVer; | ||
| 494 | switch( uVer ) | ||
| 495 | { | ||
| 496 | case 0: | ||
| 497 | ar >> hIndex; | ||
| 498 | break; | ||
| 499 | } | ||
| 291 | } | 500 | } |
| 292 | catch(...) | 501 | catch(...) |
| 293 | { | 502 | { |
| 294 | if( mStore.createStreamWithId( 1 ) != 1 ) | 503 | if( mStore.createStreamWithId( 1 ) != 1 ) |
| 295 | throw Bu::ExceptionBase("Error creating index stream."); | 504 | throw Bu::ExceptionBase("Error creating index stream."); |
| 296 | 505 | ||
| 297 | Bu::MyriadStream ms = mStore.openStream( 1 ); | 506 | sync(); |
| 298 | Bu::Archive ar( ms, Bu::Archive::save ); | ||
| 299 | ar << hIndex; | ||
| 300 | } | 507 | } |
| 301 | } | 508 | } |
| 302 | 509 | ||
| @@ -318,7 +525,7 @@ public: | |||
| 318 | Bu::ReadWriteMutex::ReadLocker wl( rwStore ); | 525 | Bu::ReadWriteMutex::ReadLocker wl( rwStore ); |
| 319 | Bu::MyriadStream ms = mStore.openStream( 1 ); | 526 | Bu::MyriadStream ms = mStore.openStream( 1 ); |
| 320 | Bu::Archive ar( ms, Bu::Archive::save ); | 527 | Bu::Archive ar( ms, Bu::Archive::save ); |
| 321 | ar << hIndex; | 528 | ar << (uint8_t)0 << hIndex; |
| 322 | ar.close(); | 529 | ar.close(); |
| 323 | ms.setSize( ms.tell() ); | 530 | ms.setSize( ms.tell() ); |
| 324 | } | 531 | } |
| @@ -413,21 +620,65 @@ Bu::ArchiveBase &operator<<( Bu::ArchiveBase &ar, const Something &s ) | |||
| 413 | typedef CachePtr<Bu::Uuid, Something> SomethingPtr; | 620 | typedef CachePtr<Bu::Uuid, Something> SomethingPtr; |
| 414 | typedef MyriadCache<Bu::Uuid, Something> SomethingCache; | 621 | typedef MyriadCache<Bu::Uuid, Something> SomethingCache; |
| 415 | 622 | ||
| 416 | int main() | 623 | int main( int argc, char *argv[] ) |
| 417 | { | 624 | { |
| 418 | Bu::File fStore("test.myr", Bu::File::Create|Bu::File::ReadWrite); | 625 | Bu::File fStore("test.myr", Bu::File::Create|Bu::File::ReadWrite); |
| 419 | SomethingCache c( fStore ); | 626 | SomethingCache c( fStore ); |
| 420 | 627 | ||
| 421 | SomethingPtr ptr = c.insert( new Something("Bob") ); | 628 | for( int j = 1; j < argc; j++ ) |
| 422 | 629 | { | |
| 423 | Bu::println("Something[%1]: %2").arg( ptr.getKey() ).arg(ptr->getName()); | 630 | SomethingPtr ptr = c.insert( new Something(argv[j]) ); |
| 424 | 631 | ||
| 632 | Bu::println("Something[%1]: %2"). | ||
| 633 | arg( ptr.getKey() ). | ||
| 634 | arg( ptr->getName() ); | ||
| 635 | } | ||
| 636 | |||
| 425 | SomethingCache::KeyList lKeys = c.getKeys(); | 637 | SomethingCache::KeyList lKeys = c.getKeys(); |
| 426 | for( SomethingCache::KeyList::iterator i = lKeys.begin(); i; i++ ) | 638 | for( SomethingCache::KeyList::iterator i = lKeys.begin(); i; i++ ) |
| 427 | { | 639 | { |
| 428 | Bu::println(" - %1").arg( *i ); | 640 | Bu::println(" - %1: '%2'").arg( *i ).arg( c.get( *i )->getName() ); |
| 429 | } | 641 | } |
| 430 | 642 | ||
| 643 | c._debug(); | ||
| 644 | |||
| 645 | SomethingPtr p2; | ||
| 646 | SomethingPtr p1( c.get( lKeys.first() ) ); | ||
| 647 | |||
| 648 | c._debug(); | ||
| 649 | |||
| 650 | { | ||
| 651 | SomethingPtr p2( p1 ); | ||
| 652 | c._debug(); | ||
| 653 | } | ||
| 654 | |||
| 655 | c._debug(); | ||
| 656 | |||
| 657 | p2 = p1; | ||
| 658 | |||
| 659 | c._debug(); | ||
| 660 | |||
| 661 | p1.release(); | ||
| 662 | |||
| 663 | c._debug(); | ||
| 664 | |||
| 665 | Bu::println("Name: %1").arg( p1->getName() ); | ||
| 666 | |||
| 667 | p1.release(); | ||
| 668 | p1.lock(); | ||
| 669 | p1.unlock(); | ||
| 670 | |||
| 671 | c._debug(); | ||
| 672 | |||
| 673 | SomethingPtr p3 = c.getLazy( lKeys.first() ); | ||
| 674 | |||
| 675 | c._debug(); | ||
| 676 | |||
| 677 | SomethingPtr::Locker l( p3 ); | ||
| 678 | |||
| 679 | Bu::println("Name again: %1").arg( p3->getName() ); | ||
| 680 | |||
| 681 | c._debug(); | ||
| 431 | 682 | ||
| 432 | return 0; | 683 | return 0; |
| 433 | } | 684 | } |
