ACE+TAO-7_0_8
[ACE_TAO.git] / ACE / apps / JAWS2 / JAWS / Cache_Manager_T.cpp
blob5dd377d766f150d077004ec20683e40fd9058fb6
1 #ifndef JAWS_CACHE_MANAGER_T_CPP
2 #define JAWS_CACHE_MANAGER_T_CPP
4 #include "JAWS/Cache_Manager_T.h"
5 #include "JAWS/Cache_Hash_T.h"
6 #include "JAWS/Cache_List_T.h"
8 // FUZZ: disable check_for_streams_include
9 #include "ace/streams.h"
11 class Cache_Manager;
13 template <class KEY, class FACTORY, class HASH_FUNC, class EQ_FUNC>
14 JAWS_Cache_Manager<KEY,FACTORY,HASH_FUNC,EQ_FUNC>
15 ::JAWS_Cache_Manager (ACE_Allocator *alloc,
16 JAWS_Cache_Object_Factory *cof,
17 size_t hashsize,
18 size_t maxsize,
19 size_t maxobjsize,
20 size_t minobjsize,
21 size_t highwater,
22 size_t lowwater,
23 int timetolive,
24 int counted)
25 : allocator_ (alloc),
26 factory_ (cof),
27 hashsize_ (hashsize),
28 maxsize_ (maxsize),
29 maxobjsize_ (maxobjsize),
30 minobjsize_ (minobjsize),
31 highwater_ (highwater),
32 lowwater_ (lowwater),
33 waterlevel_ (0),
34 timetolive_ (timetolive),
35 counted_ (counted),
36 hash_ (0),
37 heap_ (0)
39 // Some sanity checking needed here --
40 if (this->lowwater_ > this->highwater_)
41 this->lowwater_ = this->highwater_ / 2;
43 if (this->maxobjsize_ > (this->highwater_ - this->lowwater_) * 1024)
44 this->maxobjsize_ = (this->highwater_ - this->lowwater_) * (1024/2);
46 if (this->minobjsize_ > this->maxobjsize_)
47 this->minobjsize_ = this->maxobjsize_ / 2;
49 if (this->allocator_ == 0)
50 this->allocator_ = ACE_Allocator::instance ();
52 if (this->factory_ == 0)
53 this->factory_ = Object_Factory::instance ();
55 ACE_NEW_MALLOC (this->hash_,
56 (Cache_Hash *)
57 this->allocator_->malloc (sizeof (Cache_Hash)),
58 Cache_Hash (alloc, hashsize));
60 if (this->hash_ == 0)
62 this->hashsize_ = 0;
63 return;
66 ACE_NEW_MALLOC (this->heap_,
67 (Cache_Heap *)
68 this->allocator_->malloc (sizeof (Cache_Heap)),
69 Cache_Heap (alloc, maxsize));
71 if (this->heap_ == 0)
73 this->maxsize_ = 0;
76 ACE_DES_FREE_TEMPLATE3(this->hash_, this->allocator_->free,
77 JAWS_Cache_Hash,
78 KEY, HASH_FUNC, EQ_FUNC);
82 this->hash_ = 0;
83 this->hashsize_ = 0;
88 template <class KEY, class FACTORY, class HASH_FUNC, class EQ_FUNC> int
89 JAWS_Cache_Manager<KEY,FACTORY,HASH_FUNC,EQ_FUNC>
90 ::open (ACE_Allocator *alloc,
91 JAWS_Cache_Object_Factory *cof,
92 size_t hashsize,
93 size_t maxsize,
94 size_t maxobjsize,
95 size_t minobjsize,
96 size_t highwater,
97 size_t lowwater,
98 int timetolive,
99 int counted)
101 this->close ();
103 this->allocator_ = alloc;
104 this->factory_ = cof;
105 this->hashsize_ = hashsize;
106 this->maxsize_ = maxsize;
107 this->maxobjsize_ = maxobjsize;
108 this->minobjsize_ = minobjsize;
109 this->highwater_ = highwater;
110 this->lowwater_ = lowwater;
111 this->waterlevel_ = 0;
112 this->timetolive_ = timetolive;
113 this->counted_ = counted;
115 // Some sanity checking needed here --
116 if (this->lowwater_ > this->highwater_)
117 this->lowwater_ = this->highwater_ / 2;
119 if (this->maxobjsize_ > (this->highwater_ - this->lowwater_) * 1024)
120 this->maxobjsize_ = (this->highwater_ - this->lowwater_) * (1024/2);
122 if (this->minobjsize_ > this->maxobjsize_)
123 this->minobjsize_ = this->maxobjsize_ / 2;
125 if (this->allocator_ == 0)
126 this->allocator_ = ACE_Allocator::instance ();
128 if (this->factory_ == 0)
129 this->factory_ = Object_Factory::instance ();
131 this->hash_ = (Cache_Hash *) this->allocator_->malloc (sizeof (Cache_Hash));
132 if (this->hash_ == 0)
134 errno = ENOMEM;
135 this->hashsize_ = 0;
137 return -1;
139 new (this->hash_) Cache_Hash (alloc, hashsize);
141 this->heap_ = (Cache_Heap *) this->allocator_->malloc (sizeof (Cache_Heap));
142 if (this->heap_ == 0)
144 errno = ENOMEM;
145 this->maxsize_ = 0;
148 ACE_DES_FREE_TEMPLATE3(this->hash_, this->allocator_->free,
149 JAWS_Cache_Hash,
150 KEY, HASH_FUNC, EQ_FUNC);
154 this->hash_ = 0;
155 this->hashsize_ = 0;
157 return -1;
159 new (this->heap_) Cache_Heap (alloc, maxsize);
161 return 0;
164 template <class KEY, class FACTORY, class HASH_FUNC, class EQ_FUNC>
165 JAWS_Cache_Manager<KEY,FACTORY,HASH_FUNC,EQ_FUNC>::~JAWS_Cache_Manager (void)
167 this->close ();
170 template <class KEY, class FACTORY, class HASH_FUNC, class EQ_FUNC> int
171 JAWS_Cache_Manager<KEY,FACTORY,HASH_FUNC,EQ_FUNC>::close (void)
173 while (this->waterlevel_ > 0)
174 this->FLUSH_i ();
176 if (this->hash_)
179 ACE_DES_FREE_TEMPLATE3(this->hash_, this->allocator_->free,
180 JAWS_Cache_Hash,
181 KEY, HASH_FUNC, EQ_FUNC);
185 this->hash_ = 0;
188 if (this->heap_)
191 ACE_DES_FREE_TEMPLATE4(this->heap_, this->allocator_->free,
192 JAWS_Cache_List,
193 KEY, FACTORY, HASH_FUNC, EQ_FUNC);
197 this->heap_ = 0;
200 return 0;
203 template <class KEY, class FACTORY, class HASH_FUNC, class EQ_FUNC> int
204 JAWS_Cache_Manager<KEY,FACTORY,HASH_FUNC,EQ_FUNC>
205 ::GET_i (const KEY &key, JAWS_Cache_Object *&object)
207 int const result = this->hash_->find (key, object);
209 if (result == 0)
210 this->TAKE (object);
211 else
212 object = 0;
214 return result;
217 template <class KEY, class FACTORY, class HASH_FUNC, class EQ_FUNC> int
218 JAWS_Cache_Manager<KEY,FACTORY,HASH_FUNC,EQ_FUNC>
219 ::PUT_i (const KEY &key, const void *data, size_t size, JAWS_Cache_Object *&obj)
221 int result = 0;
223 if (data == 0)
225 this->FLUSH_i (key);
226 obj = 0;
227 return 0;
230 result = this->MAKE (data, size, obj);
231 if (result == -1)
233 if (size/1024 <= this->maxobjsize_)
234 cerr << "MAKE failed. Bummer!" << endl;
235 else
236 this->DROP_i (obj);
237 return -1;
240 obj->internal (new KEY (key));
242 KEY old_key;
243 JAWS_Cache_Object *old_obj;
245 result = this->hash_->rebind (key, obj, old_key, old_obj);
246 if (result == -1)
248 cerr << "*** hash bind error: " << key << endl;
249 obj->release ();
250 this->DROP_i (obj);
251 return -1;
253 else if (result == 1)
255 this->heap_->remove (old_obj->heap_item ());
256 this->waterlevel_ -= old_obj->size ();
257 old_obj->release ();
258 this->DROP_i (old_obj);
261 result = this->heap_->insert (key, obj);
262 if (result == -1)
264 cerr << "*** heap insertion error: " << key << endl;
265 this->hash_->unbind (key);
266 obj->release ();
267 this->DROP_i (obj);
268 return -1;
271 this->waterlevel_ += size;
273 // Acquire this one for the putter.
274 this->TAKE (obj);
276 return 0;
279 template <class KEY, class FACTORY, class HASH_FUNC, class EQ_FUNC> int
280 JAWS_Cache_Manager<KEY,FACTORY,HASH_FUNC,EQ_FUNC>
281 ::FLUSH_i (const KEY &key)
283 JAWS_Cache_Object *temp_object;
285 #ifdef ENTERA_VERBOSE_TRACE
286 cerr << "*** flush key unbinding: " << key << endl;
287 #endif
288 int result = this->hash_->unbind (key, temp_object);
289 if (result == 0)
291 this->waterlevel_ -= temp_object->size ();
292 if (this->heap_->remove (temp_object->heap_item ()) == -1)
293 cerr << "*** flush key heap remove failed: " << endl;
294 temp_object->release ();
295 this->DROP_i (temp_object);
297 else
298 cerr << "*** flush key hash unbind failed: " << key << endl;
300 return result;
303 template <class KEY, class FACTORY, class HASH_FUNC, class EQ_FUNC> int
304 JAWS_Cache_Manager<KEY,FACTORY,HASH_FUNC,EQ_FUNC>
305 ::FLUSH_i (void)
307 KEY temp_key;
308 JAWS_Cache_Object *temp_object;
310 int result = this->heap_->remove (temp_key, temp_object);
311 if (result == 0)
313 #ifdef ENTERA_VERBOSE_TRACE
314 cerr << "*** flush unbinding: " << temp_key << endl;
315 #endif
316 result = this->hash_->unbind (temp_key);
317 if (result == -1)
318 cerr << "*** flush hash unbind failed: " << temp_key << endl;
319 result = 0;
320 this->waterlevel_ -= temp_object->size ();
321 temp_object->release ();
322 this->DROP_i (temp_object);
324 else
326 cerr << "*** flush heap remove failed" << endl;
329 return result;
332 template <class KEY, class FACTORY, class HASH_FUNC, class EQ_FUNC> int
333 JAWS_Cache_Manager<KEY,FACTORY,HASH_FUNC,EQ_FUNC>
334 ::DROP_i (JAWS_Cache_Object *&obj)
336 int result = 0;
338 if (obj->count () == 0)
340 KEY *key = (KEY *) obj->internal ();
341 this->factory_->destroy (obj);
342 delete key;
343 obj = 0;
344 result = 1;
346 else
347 result = this->heap_->adjust (obj->heap_item ());
349 return result;
352 template <class KEY, class FACTORY, class HASH_FUNC, class EQ_FUNC> int
353 JAWS_Cache_Manager<KEY,FACTORY,HASH_FUNC,EQ_FUNC>
354 ::GET (const KEY &key, JAWS_Cache_Object *&object)
356 ACE_READ_GUARD_RETURN (ACE_SYNCH_RW_MUTEX, g,this->lock_, -1);
358 return this->GET_i (key, object);
361 template <class KEY, class FACTORY, class HASH_FUNC, class EQ_FUNC> int
362 JAWS_Cache_Manager<KEY,FACTORY,HASH_FUNC,EQ_FUNC>
363 ::PUT (const KEY &key, const void *data, size_t size, JAWS_Cache_Object *&obj)
365 ACE_WRITE_GUARD_RETURN (ACE_SYNCH_RW_MUTEX, g,this->lock_, -1);
367 return this->PUT_i (key, data, size, obj);
370 template <class KEY, class FACTORY, class HASH_FUNC, class EQ_FUNC> int
371 JAWS_Cache_Manager<KEY,FACTORY,HASH_FUNC,EQ_FUNC>
372 ::MAKE (const void *data, size_t size, JAWS_Cache_Object *&obj)
374 // verify object is within cacheable range
375 if (size/1024 > this->maxobjsize_)
377 #if 0
378 // What we do is cache it anyway, but remove it as soon as the
379 // requester returns it.
380 obj = this->factory_->create (data, size);
381 return 0;
382 #else
383 // The above is a little tricky to implement. Think about it
384 // some more.
385 obj = this->factory_->create (data, size);
386 return -1;
388 #endif /* 0 */
391 if (size/1024 < this->minobjsize_)
394 // Don't bother to cache this.
395 cerr << "*** " << static_cast<unsigned int>(size) << " is too small to cache" << endl;
396 return -1;
399 // make sure we have sufficient memory
400 if (this->waterlevel_ + size > this->highwater_ * (1024 * 1024))
404 if (this->FLUSH_i () == -1)
406 cerr << "*** cache flooded, flush error" << endl;
407 return -1;
410 while (this->waterlevel_ > this->lowwater_ * (1024 * 1024));
413 // make sure heap has enough room
414 if (this->heap_->is_full ())
416 cerr << "*** heap full, flushing" << endl;
417 if (this->FLUSH_i () == -1)
419 cerr << "*** heap full, flush error" << endl;
420 return -1;
424 obj = this->factory_->create (data, size);
425 if (this->TAKE (obj) == -1)
427 cerr << "*** take error" << endl;
428 this->factory_->destroy (obj);
429 obj = 0;
430 return -1;
433 return 0;
436 template <class KEY, class FACTORY, class HASH_FUNC, class EQ_FUNC> int
437 JAWS_Cache_Manager<KEY,FACTORY,HASH_FUNC,EQ_FUNC>
438 ::TAKE (JAWS_Cache_Object *const &obj)
440 if (obj == 0)
441 return -1;
443 return obj->acquire ();
446 template <class KEY, class FACTORY, class HASH_FUNC, class EQ_FUNC> int
447 JAWS_Cache_Manager<KEY,FACTORY,HASH_FUNC,EQ_FUNC>
448 ::DROP (JAWS_Cache_Object *&obj)
450 if (obj == 0)
451 return -1;
453 ACE_WRITE_GUARD_RETURN (ACE_SYNCH_RW_MUTEX, g, this->lock_, -1);
455 int result = obj->release ();
457 if (result == 0)
459 if (obj->count () == 0)
461 KEY *key = (KEY *) obj->internal ();
462 this->factory_->destroy (obj);
463 delete key;
464 obj = 0;
465 result = 1;
467 else
469 result = this->DROP_i (obj);
473 return result;
476 template <class KEY, class FACTORY, class HASH_FUNC, class EQ_FUNC> int
477 JAWS_Cache_Manager<KEY,FACTORY,HASH_FUNC,EQ_FUNC>
478 ::FLUSH (void)
480 ACE_WRITE_GUARD_RETURN (ACE_SYNCH_RW_MUTEX, g, this->lock_, -1);
482 return this->FLUSH_i ();
486 template <class KEY, class DATA, class CACHE_MANAGER>
487 JAWS_Cache_Proxy<KEY, DATA, CACHE_MANAGER>
488 ::JAWS_Cache_Proxy (const KEY &key, Cache_Manager *manager)
489 : object_ (0),
490 manager_ (manager)
492 if (this->manager_ == 0)
493 this->manager_ = Cache_Manager_Singleton::instance ();
495 int const result = this->manager_->GET (key, this->object_);
496 if (result == -1)
497 this->object_ = 0;
500 template <class KEY, class DATA, class CACHE_MANAGER>
501 JAWS_Cache_Proxy<KEY, DATA, CACHE_MANAGER>
502 ::JAWS_Cache_Proxy (const KEY &key, DATA *data, size_t size,
503 Cache_Manager *manager)
504 : object_ (0),
505 manager_ (manager)
507 if (this->manager_ == 0)
508 this->manager_ = Cache_Manager_Singleton::instance ();
510 int result = this->manager_->PUT (key, data, size, this->object_);
511 if (result == -1)
512 this->object_ = 0;
515 template <class KEY, class DATA, class CACHE_MANAGER>
516 JAWS_Cache_Proxy<KEY, DATA, CACHE_MANAGER>::~JAWS_Cache_Proxy (void)
518 DATA *data = this->data ();
519 this->manager_->DROP (this->object_);
520 if (this->object_ == 0)
521 this->close (data);
524 template <class KEY, class DATA, class CACHE_MANAGER> DATA *
525 JAWS_Cache_Proxy<KEY, DATA, CACHE_MANAGER>::data () const
527 return this->object_ ? (DATA *) this->object_->data () : 0;
530 template <class KEY, class DATA, class CACHE_MANAGER>
531 JAWS_Cache_Proxy<KEY, DATA, CACHE_MANAGER>::operator DATA * () const
533 return this->data ();
536 template <class KEY, class DATA, class CACHE_MANAGER> int
537 JAWS_Cache_Proxy<KEY, DATA, CACHE_MANAGER>::close (DATA *)
539 return 0;
543 #endif /* JAWS_CACHE_MANAGER_T_CPP */