diff options
author | Mike Buland <eichlan@xagasoft.com> | 2013-03-13 02:50:06 +0000 |
---|---|---|
committer | Mike Buland <eichlan@xagasoft.com> | 2013-03-13 02:50:06 +0000 |
commit | 0ac226c809b6495d5dbc09c2f847638e10aca315 (patch) | |
tree | f01e3af3320bdb93e9bc029ae760fa5518c0d5c8 /src | |
parent | a7c44a1356a8ee1384d70dd98941e00c89ec2702 (diff) | |
download | libbu++-0ac226c809b6495d5dbc09c2f847638e10aca315.tar.gz libbu++-0ac226c809b6495d5dbc09c2f847638e10aca315.tar.bz2 libbu++-0ac226c809b6495d5dbc09c2f847638e10aca315.tar.xz libbu++-0ac226c809b6495d5dbc09c2f847638e10aca315.zip |
The new caching system is almost there. It's more elaborate internally, and
it works very, very differently, but the interface is proving much easier to
use and it should be much faster, not to mention thread-safe.
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 | } |