?? cache_manager_t.cpp
字號:
// Cache_Manager_T.cpp,v 1.4 2000/05/31 19:15:07 jxh Exp
#ifndef JAWS_CACHE_MANAGER_T_CPP
#define JAWS_CACHE_MANAGER_T_CPP
#include "JAWS/Cache_Manager_T.h"
#include "JAWS/Cache_Hash_T.h"
#include "JAWS/Cache_List_T.h"
class Cache_Manager;
template <class KEY, class FACTORY, class HASH_FUNC, class EQ_FUNC>
JAWS_Cache_Manager<KEY,FACTORY,HASH_FUNC,EQ_FUNC>
::JAWS_Cache_Manager (ACE_Allocator *alloc,
JAWS_Cache_Object_Factory *cof,
size_t hashsize,
size_t maxsize,
size_t maxobjsize,
size_t minobjsize,
size_t highwater,
size_t lowwater,
int timetolive,
int counted)
: allocator_ (alloc),
factory_ (cof),
hashsize_ (hashsize),
maxsize_ (maxsize),
maxobjsize_ (maxobjsize),
minobjsize_ (minobjsize),
highwater_ (highwater),
lowwater_ (lowwater),
waterlevel_ (0),
timetolive_ (timetolive),
counted_ (counted),
hash_ (0),
heap_ (0)
{
// Some sanity checking needed here --
if (this->lowwater_ > this->highwater_)
this->lowwater_ = this->highwater_ / 2;
if (this->maxobjsize_ > (this->highwater_ - this->lowwater_) * 1024)
this->maxobjsize_ = (this->highwater_ - this->lowwater_) * (1024/2);
if (this->minobjsize_ > this->maxobjsize_)
this->minobjsize_ = this->maxobjsize_ / 2;
if (this->allocator_ == 0)
this->allocator_ = ACE_Allocator::instance ();
if (this->factory_ == 0)
this->factory_ = Object_Factory::instance ();
ACE_NEW_MALLOC (this->hash_,
(Cache_Hash *)
this->allocator_->malloc (sizeof (Cache_Hash)),
Cache_Hash (alloc, hashsize));
if (this->hash_ == 0)
{
this->hashsize_ = 0;
return;
}
ACE_NEW_MALLOC (this->heap_,
(Cache_Heap *)
this->allocator_->malloc (sizeof (Cache_Heap)),
Cache_Heap (alloc, maxsize));
if (this->heap_ == 0)
{
this->maxsize_ = 0;
ACE_DES_FREE_TEMPLATE3(this->hash_, this->allocator_->free,
JAWS_Cache_Hash,
KEY, HASH_FUNC, EQ_FUNC);
this->hash_ = 0;
this->hashsize_ = 0;
}
}
template <class KEY, class FACTORY, class HASH_FUNC, class EQ_FUNC> int
JAWS_Cache_Manager<KEY,FACTORY,HASH_FUNC,EQ_FUNC>
::open (ACE_Allocator *alloc,
JAWS_Cache_Object_Factory *cof,
size_t hashsize,
size_t maxsize,
size_t maxobjsize,
size_t minobjsize,
size_t highwater,
size_t lowwater,
int timetolive,
int counted)
{
this->close ();
this->allocator_ = alloc;
this->factory_ = cof;
this->hashsize_ = hashsize;
this->maxsize_ = maxsize;
this->maxobjsize_ = maxobjsize;
this->minobjsize_ = minobjsize;
this->highwater_ = highwater;
this->lowwater_ = lowwater;
this->waterlevel_ = 0;
this->timetolive_ = timetolive;
this->counted_ = counted;
// Some sanity checking needed here --
if (this->lowwater_ > this->highwater_)
this->lowwater_ = this->highwater_ / 2;
if (this->maxobjsize_ > (this->highwater_ - this->lowwater_) * 1024)
this->maxobjsize_ = (this->highwater_ - this->lowwater_) * (1024/2);
if (this->minobjsize_ > this->maxobjsize_)
this->minobjsize_ = this->maxobjsize_ / 2;
if (this->allocator_ == 0)
this->allocator_ = ACE_Allocator::instance ();
if (this->factory_ == 0)
this->factory_ = Object_Factory::instance ();
this->hash_ = (Cache_Hash *) this->allocator_->malloc (sizeof (Cache_Hash));
if (this->hash_ == 0)
{
errno = ENOMEM;
this->hashsize_ = 0;
return -1;
}
new (this->hash_) Cache_Hash (alloc, hashsize);
this->heap_ = (Cache_Heap *) this->allocator_->malloc (sizeof (Cache_Heap));
if (this->heap_ == 0)
{
errno = ENOMEM;
this->maxsize_ = 0;
ACE_DES_FREE_TEMPLATE3(this->hash_, this->allocator_->free,
JAWS_Cache_Hash,
KEY, HASH_FUNC, EQ_FUNC);
this->hash_ = 0;
this->hashsize_ = 0;
return -1;
}
new (this->heap_) Cache_Heap (alloc, maxsize);
return 0;
}
template <class KEY, class FACTORY, class HASH_FUNC, class EQ_FUNC>
JAWS_Cache_Manager<KEY,FACTORY,HASH_FUNC,EQ_FUNC>::~JAWS_Cache_Manager (void)
{
this->close ();
}
template <class KEY, class FACTORY, class HASH_FUNC, class EQ_FUNC> int
JAWS_Cache_Manager<KEY,FACTORY,HASH_FUNC,EQ_FUNC>::close (void)
{
while (this->waterlevel_ > 0)
this->FLUSH_i ();
if (this->hash_)
{
ACE_DES_FREE_TEMPLATE3(this->hash_, this->allocator_->free,
JAWS_Cache_Hash,
KEY, HASH_FUNC, EQ_FUNC);
this->hash_ = 0;
}
if (this->heap_)
{
ACE_DES_FREE_TEMPLATE4(this->heap_, this->allocator_->free,
JAWS_Cache_List,
KEY, FACTORY, HASH_FUNC, EQ_FUNC);
this->heap_ = 0;
}
return 0;
}
template <class KEY, class FACTORY, class HASH_FUNC, class EQ_FUNC> int
JAWS_Cache_Manager<KEY,FACTORY,HASH_FUNC,EQ_FUNC>
::GET_i (const KEY &key, JAWS_Cache_Object *&object)
{
int result = this->hash_->find (key, object);
if (result == 0)
this->TAKE (object);
else
object = 0;
return result;
}
template <class KEY, class FACTORY, class HASH_FUNC, class EQ_FUNC> int
JAWS_Cache_Manager<KEY,FACTORY,HASH_FUNC,EQ_FUNC>
::PUT_i (const KEY &key, const void *data, size_t size, JAWS_Cache_Object *&obj)
{
int result = 0;
if (data == 0)
{
this->FLUSH_i (key);
obj = 0;
return 0;
}
result = this->MAKE (data, size, obj);
if (result == -1)
{
if (size/1024 <= this->maxobjsize_)
cerr << "MAKE failed. Bummer!" << endl;
else
this->DROP_i (obj);
return -1;
}
obj->internal (new KEY (key));
KEY old_key;
JAWS_Cache_Object *old_obj;
result = this->hash_->rebind (key, obj, old_key, old_obj);
if (result == -1)
{
cerr << "*** hash bind error: " << key << endl;
obj->release ();
this->DROP_i (obj);
return -1;
}
else if (result == 1)
{
this->heap_->remove (old_obj->heap_item ());
this->waterlevel_ -= old_obj->size ();
old_obj->release ();
this->DROP_i (old_obj);
}
result = this->heap_->insert (key, obj);
if (result == -1)
{
cerr << "*** heap insertion error: " << key << endl;
this->hash_->unbind (key);
obj->release ();
this->DROP_i (obj);
return -1;
}
this->waterlevel_ += size;
// Acquire this one for the putter.
this->TAKE (obj);
return 0;
}
template <class KEY, class FACTORY, class HASH_FUNC, class EQ_FUNC> int
JAWS_Cache_Manager<KEY,FACTORY,HASH_FUNC,EQ_FUNC>
::FLUSH_i (const KEY &key)
{
JAWS_Cache_Object *temp_object;
#ifdef ENTERA_VERBOSE_TRACE
cerr << "*** flush key unbinding: " << key << endl;
#endif
int result = this->hash_->unbind (key, temp_object);
if (result == 0)
{
this->waterlevel_ -= temp_object->size ();
if (this->heap_->remove (temp_object->heap_item ()) == -1)
cerr << "*** flush key heap remove failed: " << endl;
temp_object->release ();
this->DROP_i (temp_object);
}
else
cerr << "*** flush key hash unbind failed: " << key << endl;
return result;
}
template <class KEY, class FACTORY, class HASH_FUNC, class EQ_FUNC> int
JAWS_Cache_Manager<KEY,FACTORY,HASH_FUNC,EQ_FUNC>
::FLUSH_i (void)
{
KEY temp_key;
JAWS_Cache_Object *temp_object;
int result = this->heap_->remove (temp_key, temp_object);
if (result == 0)
{
#ifdef ENTERA_VERBOSE_TRACE
cerr << "*** flush unbinding: " << temp_key << endl;
#endif
result = this->hash_->unbind (temp_key);
if (result == -1)
cerr << "*** flush hash unbind failed: " << temp_key << endl;
result = 0;
this->waterlevel_ -= temp_object->size ();
temp_object->release ();
this->DROP_i (temp_object);
}
else
{
cerr << "*** flush heap remove failed" << endl;
}
return result;
}
template <class KEY, class FACTORY, class HASH_FUNC, class EQ_FUNC> int
JAWS_Cache_Manager<KEY,FACTORY,HASH_FUNC,EQ_FUNC>
::DROP_i (JAWS_Cache_Object *&obj)
{
int result = 0;
if (obj->count () == 0)
{
KEY *key = (KEY *) obj->internal ();
this->factory_->destroy (obj);
delete key;
obj = 0;
result = 1;
}
else
result = this->heap_->adjust (obj->heap_item ());
return result;
}
template <class KEY, class FACTORY, class HASH_FUNC, class EQ_FUNC> int
JAWS_Cache_Manager<KEY,FACTORY,HASH_FUNC,EQ_FUNC>
::GET (const KEY &key, JAWS_Cache_Object *&object)
{
ACE_Read_Guard<ACE_SYNCH_RW_MUTEX> g (this->lock_);
return this->GET_i (key, object);
}
template <class KEY, class FACTORY, class HASH_FUNC, class EQ_FUNC> int
JAWS_Cache_Manager<KEY,FACTORY,HASH_FUNC,EQ_FUNC>
::PUT (const KEY &key, const void *data, size_t size, JAWS_Cache_Object *&obj)
{
ACE_Write_Guard<ACE_SYNCH_RW_MUTEX> g (this->lock_);
return this->PUT_i (key, data, size, obj);
}
template <class KEY, class FACTORY, class HASH_FUNC, class EQ_FUNC> int
JAWS_Cache_Manager<KEY,FACTORY,HASH_FUNC,EQ_FUNC>
::MAKE (const void *data, size_t size, JAWS_Cache_Object *&obj)
{
// verify object is within cacheable range
if (size/1024 > this->maxobjsize_)
{
#if 0
// What we do is cache it anyway, but remove it as soon as the
// requester returns it.
obj = this->factory_->create (data, size);
return 0;
#else
// The above is a little tricky to implement. Think about it
// some more.
obj = this->factory_->create (data, size);
return -1;
#endif /* 0 */
}
if (size/1024 < this->minobjsize_)
{
// Don't bother to cache this.
cerr << "*** " << size << " is too small to cache" << endl;
return -1;
}
// make sure we have sufficient memory
if (this->waterlevel_ + size > this->highwater_ * (1024 * 1024))
{
do
{
if (this->FLUSH_i () == -1)
{
cerr << "*** cache flooded, flush error" << endl;
return -1;
}
}
while (this->waterlevel_ > this->lowwater_ * (1024 * 1024));
}
// make sure heap has enough room
if (this->heap_->is_full ())
{
cerr << "*** heap full, flushing" << endl;
if (this->FLUSH_i () == -1)
{
cerr << "*** heap full, flush error" << endl;
return -1;
}
}
obj = this->factory_->create (data, size);
if (this->TAKE (obj) == -1)
{
cerr << "*** take error" << endl;
this->factory_->destroy (obj);
obj = 0;
return -1;
}
return 0;
}
template <class KEY, class FACTORY, class HASH_FUNC, class EQ_FUNC> int
JAWS_Cache_Manager<KEY,FACTORY,HASH_FUNC,EQ_FUNC>
::TAKE (JAWS_Cache_Object *const &obj)
{
if (obj == 0)
return -1;
return obj->acquire ();
}
template <class KEY, class FACTORY, class HASH_FUNC, class EQ_FUNC> int
JAWS_Cache_Manager<KEY,FACTORY,HASH_FUNC,EQ_FUNC>
::DROP (JAWS_Cache_Object *&obj)
{
if (obj == 0)
return -1;
#if 0
if (obj->size ()/1024 > this->maxobjsize_)
{
ACE_Write_Guard<ACE_SYNCH_RW_MUTEX> g (this->lock_);
int result = obj->release ();
if (result == 0)
{
if (obj->count () == 0)
{
KEY *key = (KEY *) obj->internal ();
#ifdef ENTERA_VERBOSE_TRACE
cerr << "*** drop large unbinding: " << key << endl;
#endif
result = this->hash_->unbind (*key);
if (result == 0)
{
if (this->heap_->remove (obj->heap_item ()) == -1)
cerr << "*** drop large heap remove failed: " << endl;
this->factory_->destroy (obj);
delete key;
obj = 0;
result = 1;
}
else
cerr << "*** drop large hash unbind failed: " << key << endl;
}
}
return result;
}
#endif /* 0 */
{
ACE_Write_Guard<ACE_SYNCH_RW_MUTEX> g (this->lock_);
int result = obj->release ();
if (result == 0)
{
if (obj->count () == 0)
{
KEY *key = (KEY *) obj->internal ();
this->factory_->destroy (obj);
delete key;
obj = 0;
result = 1;
}
else
{
result = this->DROP_i (obj);
}
}
return result;
}
}
template <class KEY, class FACTORY, class HASH_FUNC, class EQ_FUNC> int
JAWS_Cache_Manager<KEY,FACTORY,HASH_FUNC,EQ_FUNC>
::FLUSH (void)
{
ACE_Write_Guard<ACE_SYNCH_RW_MUTEX> g (this->lock_);
return this->FLUSH_i ();
}
template <class KEY, class DATA, class CACHE_MANAGER>
JAWS_Cache_Proxy<KEY, DATA, CACHE_MANAGER>
::JAWS_Cache_Proxy (const KEY &key, Cache_Manager *manager)
: object_ (0),
manager_ (manager)
{
if (this->manager_ == 0)
this->manager_ = Cache_Manager_Singleton::instance ();
int result = this->manager_->GET (key, this->object_);
if (result == -1)
this->object_ = 0;
}
template <class KEY, class DATA, class CACHE_MANAGER>
JAWS_Cache_Proxy<KEY, DATA, CACHE_MANAGER>
::JAWS_Cache_Proxy (const KEY &key, DATA *data, size_t size,
Cache_Manager *manager)
: object_ (0),
manager_ (manager)
{
if (this->manager_ == 0)
this->manager_ = Cache_Manager_Singleton::instance ();
int result = this->manager_->PUT (key, data, size, this->object_);
if (result == -1)
this->object_ = 0;
}
template <class KEY, class DATA, class CACHE_MANAGER>
JAWS_Cache_Proxy<KEY, DATA, CACHE_MANAGER>::~JAWS_Cache_Proxy (void)
{
DATA *data = this->data ();
this->manager_->DROP (this->object_);
if (this->object_ == 0)
this->close (data);
}
template <class KEY, class DATA, class CACHE_MANAGER> DATA *
JAWS_Cache_Proxy<KEY, DATA, CACHE_MANAGER>::data (void) const
{
return this->object_ ? (DATA *) this->object_->data () : 0;
}
template <class KEY, class DATA, class CACHE_MANAGER>
JAWS_Cache_Proxy<KEY, DATA, CACHE_MANAGER>::operator DATA * (void) const
{
return this->data ();
}
template <class KEY, class DATA, class CACHE_MANAGER> int
JAWS_Cache_Proxy<KEY, DATA, CACHE_MANAGER>::close (DATA *)
{
return 0;
}
#endif /* JAWS_CACHE_MANAGER_T_CPP */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -