Merge branch 'master' into jwi-bcc64xsingletonwarning
[ACE_TAO.git] / ACE / apps / JAWS2 / JAWS / Cache_Manager_T.cpp
blob2165e3d43ed6eafd47589f668076c7f04730325d
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);
81 this->hash_ = 0;
82 this->hashsize_ = 0;
87 template <class KEY, class FACTORY, class HASH_FUNC, class EQ_FUNC> int
88 JAWS_Cache_Manager<KEY,FACTORY,HASH_FUNC,EQ_FUNC>
89 ::open (ACE_Allocator *alloc,
90 JAWS_Cache_Object_Factory *cof,
91 size_t hashsize,
92 size_t maxsize,
93 size_t maxobjsize,
94 size_t minobjsize,
95 size_t highwater,
96 size_t lowwater,
97 int timetolive,
98 int counted)
100 this->close ();
102 this->allocator_ = alloc;
103 this->factory_ = cof;
104 this->hashsize_ = hashsize;
105 this->maxsize_ = maxsize;
106 this->maxobjsize_ = maxobjsize;
107 this->minobjsize_ = minobjsize;
108 this->highwater_ = highwater;
109 this->lowwater_ = lowwater;
110 this->waterlevel_ = 0;
111 this->timetolive_ = timetolive;
112 this->counted_ = counted;
114 // Some sanity checking needed here --
115 if (this->lowwater_ > this->highwater_)
116 this->lowwater_ = this->highwater_ / 2;
118 if (this->maxobjsize_ > (this->highwater_ - this->lowwater_) * 1024)
119 this->maxobjsize_ = (this->highwater_ - this->lowwater_) * (1024/2);
121 if (this->minobjsize_ > this->maxobjsize_)
122 this->minobjsize_ = this->maxobjsize_ / 2;
124 if (this->allocator_ == 0)
125 this->allocator_ = ACE_Allocator::instance ();
127 if (this->factory_ == 0)
128 this->factory_ = Object_Factory::instance ();
130 this->hash_ = (Cache_Hash *) this->allocator_->malloc (sizeof (Cache_Hash));
131 if (this->hash_ == 0)
133 errno = ENOMEM;
134 this->hashsize_ = 0;
136 return -1;
138 new (this->hash_) Cache_Hash (alloc, hashsize);
140 this->heap_ = (Cache_Heap *) this->allocator_->malloc (sizeof (Cache_Heap));
141 if (this->heap_ == 0)
143 errno = ENOMEM;
144 this->maxsize_ = 0;
147 ACE_DES_FREE_TEMPLATE3(this->hash_, this->allocator_->free,
148 JAWS_Cache_Hash,
149 KEY, HASH_FUNC, EQ_FUNC);
152 this->hash_ = 0;
153 this->hashsize_ = 0;
155 return -1;
157 new (this->heap_) Cache_Heap (alloc, maxsize);
159 return 0;
162 template <class KEY, class FACTORY, class HASH_FUNC, class EQ_FUNC>
163 JAWS_Cache_Manager<KEY,FACTORY,HASH_FUNC,EQ_FUNC>::~JAWS_Cache_Manager ()
165 this->close ();
168 template <class KEY, class FACTORY, class HASH_FUNC, class EQ_FUNC> int
169 JAWS_Cache_Manager<KEY,FACTORY,HASH_FUNC,EQ_FUNC>::close ()
171 while (this->waterlevel_ > 0)
172 this->FLUSH_i ();
174 if (this->hash_)
176 ACE_DES_FREE_TEMPLATE3(this->hash_, this->allocator_->free,
177 JAWS_Cache_Hash,
178 KEY, HASH_FUNC, EQ_FUNC);
181 this->hash_ = 0;
184 if (this->heap_)
186 ACE_DES_FREE_TEMPLATE4(this->heap_, this->allocator_->free,
187 JAWS_Cache_List,
188 KEY, FACTORY, HASH_FUNC, EQ_FUNC);
191 this->heap_ = 0;
194 return 0;
197 template <class KEY, class FACTORY, class HASH_FUNC, class EQ_FUNC> int
198 JAWS_Cache_Manager<KEY,FACTORY,HASH_FUNC,EQ_FUNC>
199 ::GET_i (const KEY &key, JAWS_Cache_Object *&object)
201 int const result = this->hash_->find (key, object);
203 if (result == 0)
204 this->TAKE (object);
205 else
206 object = 0;
208 return result;
211 template <class KEY, class FACTORY, class HASH_FUNC, class EQ_FUNC> int
212 JAWS_Cache_Manager<KEY,FACTORY,HASH_FUNC,EQ_FUNC>
213 ::PUT_i (const KEY &key, const void *data, size_t size, JAWS_Cache_Object *&obj)
215 int result = 0;
217 if (data == 0)
219 this->FLUSH_i (key);
220 obj = 0;
221 return 0;
224 result = this->MAKE (data, size, obj);
225 if (result == -1)
227 if (size/1024 <= this->maxobjsize_)
228 cerr << "MAKE failed. Bummer!" << endl;
229 else
230 this->DROP_i (obj);
231 return -1;
234 obj->internal (new KEY (key));
236 KEY old_key;
237 JAWS_Cache_Object *old_obj;
239 result = this->hash_->rebind (key, obj, old_key, old_obj);
240 if (result == -1)
242 cerr << "*** hash bind error: " << key << endl;
243 obj->release ();
244 this->DROP_i (obj);
245 return -1;
247 else if (result == 1)
249 this->heap_->remove (old_obj->heap_item ());
250 this->waterlevel_ -= old_obj->size ();
251 old_obj->release ();
252 this->DROP_i (old_obj);
255 result = this->heap_->insert (key, obj);
256 if (result == -1)
258 cerr << "*** heap insertion error: " << key << endl;
259 this->hash_->unbind (key);
260 obj->release ();
261 this->DROP_i (obj);
262 return -1;
265 this->waterlevel_ += size;
267 // Acquire this one for the putter.
268 this->TAKE (obj);
270 return 0;
273 template <class KEY, class FACTORY, class HASH_FUNC, class EQ_FUNC> int
274 JAWS_Cache_Manager<KEY,FACTORY,HASH_FUNC,EQ_FUNC>
275 ::FLUSH_i (const KEY &key)
277 JAWS_Cache_Object *temp_object;
279 #ifdef ENTERA_VERBOSE_TRACE
280 cerr << "*** flush key unbinding: " << key << endl;
281 #endif
282 int result = this->hash_->unbind (key, temp_object);
283 if (result == 0)
285 this->waterlevel_ -= temp_object->size ();
286 if (this->heap_->remove (temp_object->heap_item ()) == -1)
287 cerr << "*** flush key heap remove failed: " << endl;
288 temp_object->release ();
289 this->DROP_i (temp_object);
291 else
292 cerr << "*** flush key hash unbind failed: " << key << endl;
294 return result;
297 template <class KEY, class FACTORY, class HASH_FUNC, class EQ_FUNC> int
298 JAWS_Cache_Manager<KEY,FACTORY,HASH_FUNC,EQ_FUNC>
299 ::FLUSH_i ()
301 KEY temp_key;
302 JAWS_Cache_Object *temp_object;
304 int result = this->heap_->remove (temp_key, temp_object);
305 if (result == 0)
307 #ifdef ENTERA_VERBOSE_TRACE
308 cerr << "*** flush unbinding: " << temp_key << endl;
309 #endif
310 result = this->hash_->unbind (temp_key);
311 if (result == -1)
312 cerr << "*** flush hash unbind failed: " << temp_key << endl;
313 result = 0;
314 this->waterlevel_ -= temp_object->size ();
315 temp_object->release ();
316 this->DROP_i (temp_object);
318 else
320 cerr << "*** flush heap remove failed" << endl;
323 return result;
326 template <class KEY, class FACTORY, class HASH_FUNC, class EQ_FUNC> int
327 JAWS_Cache_Manager<KEY,FACTORY,HASH_FUNC,EQ_FUNC>
328 ::DROP_i (JAWS_Cache_Object *&obj)
330 int result = 0;
332 if (obj->count () == 0)
334 KEY *key = (KEY *) obj->internal ();
335 this->factory_->destroy (obj);
336 delete key;
337 obj = 0;
338 result = 1;
340 else
341 result = this->heap_->adjust (obj->heap_item ());
343 return result;
346 template <class KEY, class FACTORY, class HASH_FUNC, class EQ_FUNC> int
347 JAWS_Cache_Manager<KEY,FACTORY,HASH_FUNC,EQ_FUNC>
348 ::GET (const KEY &key, JAWS_Cache_Object *&object)
350 ACE_READ_GUARD_RETURN (ACE_SYNCH_RW_MUTEX, g,this->lock_, -1);
352 return this->GET_i (key, object);
355 template <class KEY, class FACTORY, class HASH_FUNC, class EQ_FUNC> int
356 JAWS_Cache_Manager<KEY,FACTORY,HASH_FUNC,EQ_FUNC>
357 ::PUT (const KEY &key, const void *data, size_t size, JAWS_Cache_Object *&obj)
359 ACE_WRITE_GUARD_RETURN (ACE_SYNCH_RW_MUTEX, g,this->lock_, -1);
361 return this->PUT_i (key, data, size, obj);
364 template <class KEY, class FACTORY, class HASH_FUNC, class EQ_FUNC> int
365 JAWS_Cache_Manager<KEY,FACTORY,HASH_FUNC,EQ_FUNC>
366 ::MAKE (const void *data, size_t size, JAWS_Cache_Object *&obj)
368 // verify object is within cacheable range
369 if (size/1024 > this->maxobjsize_)
371 #if 0
372 // What we do is cache it anyway, but remove it as soon as the
373 // requester returns it.
374 obj = this->factory_->create (data, size);
375 return 0;
376 #else
377 // The above is a little tricky to implement. Think about it
378 // some more.
379 obj = this->factory_->create (data, size);
380 return -1;
382 #endif /* 0 */
385 if (size/1024 < this->minobjsize_)
388 // Don't bother to cache this.
389 cerr << "*** " << static_cast<unsigned int>(size) << " is too small to cache" << endl;
390 return -1;
393 // make sure we have sufficient memory
394 if (this->waterlevel_ + size > this->highwater_ * (1024 * 1024))
398 if (this->FLUSH_i () == -1)
400 cerr << "*** cache flooded, flush error" << endl;
401 return -1;
404 while (this->waterlevel_ > this->lowwater_ * (1024 * 1024));
407 // make sure heap has enough room
408 if (this->heap_->is_full ())
410 cerr << "*** heap full, flushing" << endl;
411 if (this->FLUSH_i () == -1)
413 cerr << "*** heap full, flush error" << endl;
414 return -1;
418 obj = this->factory_->create (data, size);
419 if (this->TAKE (obj) == -1)
421 cerr << "*** take error" << endl;
422 this->factory_->destroy (obj);
423 obj = 0;
424 return -1;
427 return 0;
430 template <class KEY, class FACTORY, class HASH_FUNC, class EQ_FUNC> int
431 JAWS_Cache_Manager<KEY,FACTORY,HASH_FUNC,EQ_FUNC>
432 ::TAKE (JAWS_Cache_Object *const &obj)
434 if (obj == 0)
435 return -1;
437 return obj->acquire ();
440 template <class KEY, class FACTORY, class HASH_FUNC, class EQ_FUNC> int
441 JAWS_Cache_Manager<KEY,FACTORY,HASH_FUNC,EQ_FUNC>
442 ::DROP (JAWS_Cache_Object *&obj)
444 if (obj == 0)
445 return -1;
447 ACE_WRITE_GUARD_RETURN (ACE_SYNCH_RW_MUTEX, g, this->lock_, -1);
449 int result = obj->release ();
451 if (result == 0)
453 if (obj->count () == 0)
455 KEY *key = (KEY *) obj->internal ();
456 this->factory_->destroy (obj);
457 delete key;
458 obj = 0;
459 result = 1;
461 else
463 result = this->DROP_i (obj);
467 return result;
470 template <class KEY, class FACTORY, class HASH_FUNC, class EQ_FUNC> int
471 JAWS_Cache_Manager<KEY,FACTORY,HASH_FUNC,EQ_FUNC>
472 ::FLUSH ()
474 ACE_WRITE_GUARD_RETURN (ACE_SYNCH_RW_MUTEX, g, this->lock_, -1);
476 return this->FLUSH_i ();
480 template <class KEY, class DATA, class CACHE_MANAGER>
481 JAWS_Cache_Proxy<KEY, DATA, CACHE_MANAGER>
482 ::JAWS_Cache_Proxy (const KEY &key, Cache_Manager *manager)
483 : object_ (0),
484 manager_ (manager)
486 if (this->manager_ == 0)
487 this->manager_ = Cache_Manager_Singleton::instance ();
489 int const result = this->manager_->GET (key, this->object_);
490 if (result == -1)
491 this->object_ = 0;
494 template <class KEY, class DATA, class CACHE_MANAGER>
495 JAWS_Cache_Proxy<KEY, DATA, CACHE_MANAGER>
496 ::JAWS_Cache_Proxy (const KEY &key, DATA *data, size_t size,
497 Cache_Manager *manager)
498 : object_ (0),
499 manager_ (manager)
501 if (this->manager_ == 0)
502 this->manager_ = Cache_Manager_Singleton::instance ();
504 int result = this->manager_->PUT (key, data, size, this->object_);
505 if (result == -1)
506 this->object_ = 0;
509 template <class KEY, class DATA, class CACHE_MANAGER>
510 JAWS_Cache_Proxy<KEY, DATA, CACHE_MANAGER>::~JAWS_Cache_Proxy ()
512 DATA *data = this->data ();
513 this->manager_->DROP (this->object_);
514 if (this->object_ == 0)
515 this->close (data);
518 template <class KEY, class DATA, class CACHE_MANAGER> DATA *
519 JAWS_Cache_Proxy<KEY, DATA, CACHE_MANAGER>::data () const
521 return this->object_ ? (DATA *) this->object_->data () : 0;
524 template <class KEY, class DATA, class CACHE_MANAGER>
525 JAWS_Cache_Proxy<KEY, DATA, CACHE_MANAGER>::operator DATA * () const
527 return this->data ();
530 template <class KEY, class DATA, class CACHE_MANAGER> int
531 JAWS_Cache_Proxy<KEY, DATA, CACHE_MANAGER>::close (DATA *)
533 return 0;
537 #endif /* JAWS_CACHE_MANAGER_T_CPP */