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 | } |