Added include statement. Removed const declaration.
git-svn-id: svn://svn.code.sf.net/p/loki-lib/code/trunk@1054 7ec92016-0320-0410-acc4-a06ded1c099a
This commit is contained in:
parent
6eb3a5a216
commit
3592916b15
1 changed files with 81 additions and 80 deletions
|
@ -4,16 +4,16 @@
|
||||||
//
|
//
|
||||||
// Code covered by the MIT License
|
// Code covered by the MIT License
|
||||||
//
|
//
|
||||||
// Permission to use, copy, modify, distribute and sell this software for any
|
// Permission to use, copy, modify, distribute and sell this software for any
|
||||||
// purpose is hereby granted without fee, provided that the above copyright
|
// purpose is hereby granted without fee, provided that the above copyright
|
||||||
// notice appear in all copies and that both that copyright notice and this
|
// notice appear in all copies and that both that copyright notice and this
|
||||||
// permission notice appear in supporting documentation.
|
// permission notice appear in supporting documentation.
|
||||||
//
|
//
|
||||||
// The authors make no representations about the suitability of this software
|
// The authors make no representations about the suitability of this software
|
||||||
// for any purpose. It is provided "as is" without express or implied warranty.
|
// for any purpose. It is provided "as is" without express or implied warranty.
|
||||||
//
|
//
|
||||||
// This code DOES NOT accompany the book:
|
// This code DOES NOT accompany the book:
|
||||||
// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
|
// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
|
||||||
// Patterns Applied". Copyright (c) 2001. Addison-Wesley.
|
// Patterns Applied". Copyright (c) 2001. Addison-Wesley.
|
||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -22,6 +22,7 @@
|
||||||
|
|
||||||
// $Id$
|
// $Id$
|
||||||
|
|
||||||
|
#include <time.h> ///< For clock_t definition.
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
@ -47,7 +48,7 @@
|
||||||
* \ingroup FactoriesGroup
|
* \ingroup FactoriesGroup
|
||||||
* \brief CachedFactory provides an extension of a Factory with caching
|
* \brief CachedFactory provides an extension of a Factory with caching
|
||||||
* support.
|
* support.
|
||||||
*
|
*
|
||||||
* Once used objects are returned to the CachedFactory that manages its
|
* Once used objects are returned to the CachedFactory that manages its
|
||||||
* destruction.
|
* destruction.
|
||||||
* If your code uses lots of "long to construct/destruct objects" using the
|
* If your code uses lots of "long to construct/destruct objects" using the
|
||||||
|
@ -64,11 +65,11 @@ namespace Loki
|
||||||
* \class SimplePointer
|
* \class SimplePointer
|
||||||
* \ingroup EncapsulationPolicyCachedFactoryGroup
|
* \ingroup EncapsulationPolicyCachedFactoryGroup
|
||||||
* \brief No encaspulation : returns the pointer
|
* \brief No encaspulation : returns the pointer
|
||||||
*
|
*
|
||||||
* This implementation does not make any encapsulation.
|
* This implementation does not make any encapsulation.
|
||||||
* It simply returns the object's pointer.
|
* It simply returns the object's pointer.
|
||||||
*/
|
*/
|
||||||
template<class AbstractProduct>
|
template<class AbstractProduct>
|
||||||
class SimplePointer
|
class SimplePointer
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
|
@ -77,7 +78,7 @@ namespace Loki
|
||||||
{
|
{
|
||||||
return pProduct;
|
return pProduct;
|
||||||
}
|
}
|
||||||
|
|
||||||
AbstractProduct* release(ProductReturn &pProduct)
|
AbstractProduct* release(ProductReturn &pProduct)
|
||||||
{
|
{
|
||||||
AbstractProduct* pPointer(pProduct);
|
AbstractProduct* pPointer(pProduct);
|
||||||
|
@ -91,7 +92,7 @@ namespace Loki
|
||||||
* \defgroup CreationPolicyCachedFactoryGroup Creation policies
|
* \defgroup CreationPolicyCachedFactoryGroup Creation policies
|
||||||
* \ingroup CachedFactoryGroup
|
* \ingroup CachedFactoryGroup
|
||||||
* \brief Defines a way to limit the creation operation.
|
* \brief Defines a way to limit the creation operation.
|
||||||
*
|
*
|
||||||
* For instance one may want to be alerted (Exception) when
|
* For instance one may want to be alerted (Exception) when
|
||||||
* - Cache has created a more than X object within the last x seconds
|
* - Cache has created a more than X object within the last x seconds
|
||||||
* - Cache creation rate has increased dramatically
|
* - Cache creation rate has increased dramatically
|
||||||
|
@ -102,7 +103,7 @@ namespace Loki
|
||||||
* \class NeverCreate
|
* \class NeverCreate
|
||||||
* \ingroup CreationPolicyCachedFactoryGroup
|
* \ingroup CreationPolicyCachedFactoryGroup
|
||||||
* \brief Never allows creation. Testing purposes only.
|
* \brief Never allows creation. Testing purposes only.
|
||||||
*
|
*
|
||||||
* Using this policy will throw an exception.
|
* Using this policy will throw an exception.
|
||||||
*/
|
*/
|
||||||
class NeverCreate
|
class NeverCreate
|
||||||
|
@ -112,22 +113,22 @@ namespace Loki
|
||||||
{
|
{
|
||||||
const char* what() const throw() { return "NeverFetch Policy : No Fetching allowed"; }
|
const char* what() const throw() { return "NeverFetch Policy : No Fetching allowed"; }
|
||||||
};
|
};
|
||||||
|
|
||||||
bool canCreate()
|
bool canCreate()
|
||||||
{
|
{
|
||||||
throw Exception();
|
throw Exception();
|
||||||
}
|
}
|
||||||
|
|
||||||
void onCreate(){}
|
void onCreate(){}
|
||||||
void onDestroy(){}
|
void onDestroy(){}
|
||||||
const char* name(){return "never";}
|
const char* name(){return "never";}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \class AlwaysCreate
|
* \class AlwaysCreate
|
||||||
* \ingroup CreationPolicyCachedFactoryGroup
|
* \ingroup CreationPolicyCachedFactoryGroup
|
||||||
* \brief Always allows creation.
|
* \brief Always allows creation.
|
||||||
*
|
*
|
||||||
* Doesn't limit the creation in any way
|
* Doesn't limit the creation in any way
|
||||||
*/
|
*/
|
||||||
class AlwaysCreate
|
class AlwaysCreate
|
||||||
|
@ -148,7 +149,7 @@ namespace Loki
|
||||||
* \class RateLimitedCreation
|
* \class RateLimitedCreation
|
||||||
* \ingroup CreationPolicyCachedFactoryGroup
|
* \ingroup CreationPolicyCachedFactoryGroup
|
||||||
* \brief Limit in rate.
|
* \brief Limit in rate.
|
||||||
*
|
*
|
||||||
* This implementation will prevent from Creating more than maxCreation objects
|
* This implementation will prevent from Creating more than maxCreation objects
|
||||||
* within byTime ms by throwing an exception.
|
* within byTime ms by throwing an exception.
|
||||||
* Could be usefull to detect prevent loads (http connection for instance).
|
* Could be usefull to detect prevent loads (http connection for instance).
|
||||||
|
@ -167,7 +168,7 @@ namespace Loki
|
||||||
unsigned maxCreation;
|
unsigned maxCreation;
|
||||||
clock_t timeValidity;
|
clock_t timeValidity;
|
||||||
clock_t lastUpdate;
|
clock_t lastUpdate;
|
||||||
|
|
||||||
void cleanVector()
|
void cleanVector()
|
||||||
{
|
{
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
@ -193,7 +194,7 @@ namespace Loki
|
||||||
}
|
}
|
||||||
lastUpdate = currentTime;
|
lastUpdate = currentTime;
|
||||||
}
|
}
|
||||||
#ifdef DO_EXTRA_LOKI_TESTS
|
#ifdef DO_EXTRA_LOKI_TESTS
|
||||||
void displayVector()
|
void displayVector()
|
||||||
{
|
{
|
||||||
std::cout << "Vector : ";
|
std::cout << "Vector : ";
|
||||||
|
@ -204,12 +205,12 @@ namespace Loki
|
||||||
protected:
|
protected:
|
||||||
RateLimitedCreation() : maxCreation(10), timeValidity(CLOCKS_PER_SEC), lastUpdate(clock())
|
RateLimitedCreation() : maxCreation(10), timeValidity(CLOCKS_PER_SEC), lastUpdate(clock())
|
||||||
{}
|
{}
|
||||||
|
|
||||||
struct Exception : public std::exception
|
struct Exception : public std::exception
|
||||||
{
|
{
|
||||||
const char* what() const throw() { return "RateLimitedCreation Policy : Exceeded the authorized creation rate"; }
|
const char* what() const throw() { return "RateLimitedCreation Policy : Exceeded the authorized creation rate"; }
|
||||||
};
|
};
|
||||||
|
|
||||||
bool canCreate()
|
bool canCreate()
|
||||||
{
|
{
|
||||||
cleanVector();
|
cleanVector();
|
||||||
|
@ -223,7 +224,7 @@ namespace Loki
|
||||||
{
|
{
|
||||||
m_vTimes.push_back(clock());
|
m_vTimes.push_back(clock());
|
||||||
}
|
}
|
||||||
|
|
||||||
void onDestroy()
|
void onDestroy()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -239,12 +240,12 @@ namespace Loki
|
||||||
D( std::cout << "Setting no more than "<< maxCreation <<" creation within " << this->timeValidity <<" ms"<< std::endl; )
|
D( std::cout << "Setting no more than "<< maxCreation <<" creation within " << this->timeValidity <<" ms"<< std::endl; )
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \class AmountLimitedCreation
|
* \class AmountLimitedCreation
|
||||||
* \ingroup CreationPolicyCachedFactoryGroup
|
* \ingroup CreationPolicyCachedFactoryGroup
|
||||||
* \brief Limit by number of objects
|
* \brief Limit by number of objects
|
||||||
*
|
*
|
||||||
* This implementation will prevent from Creating more than maxCreation objects
|
* This implementation will prevent from Creating more than maxCreation objects
|
||||||
* within byTime ms by calling eviction policy.
|
* within byTime ms by calling eviction policy.
|
||||||
* Use the setRate method to set the rate parameters.
|
* Use the setRate method to set the rate parameters.
|
||||||
|
@ -255,11 +256,11 @@ namespace Loki
|
||||||
private:
|
private:
|
||||||
unsigned maxCreation;
|
unsigned maxCreation;
|
||||||
unsigned created;
|
unsigned created;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
AmountLimitedCreation() : maxCreation(10), created(0)
|
AmountLimitedCreation() : maxCreation(10), created(0)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
bool canCreate()
|
bool canCreate()
|
||||||
{
|
{
|
||||||
return !(created>=maxCreation);
|
return !(created>=maxCreation);
|
||||||
|
@ -269,7 +270,7 @@ namespace Loki
|
||||||
{
|
{
|
||||||
++created;
|
++created;
|
||||||
}
|
}
|
||||||
|
|
||||||
void onDestroy()
|
void onDestroy()
|
||||||
{
|
{
|
||||||
--created;
|
--created;
|
||||||
|
@ -284,7 +285,7 @@ namespace Loki
|
||||||
D( std::cout << "Setting no more than " << maxCreation <<" creation" << std::endl; )
|
D( std::cout << "Setting no more than " << maxCreation <<" creation" << std::endl; )
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \defgroup EvictionPolicyCachedFactoryGroup Eviction policies
|
* \defgroup EvictionPolicyCachedFactoryGroup Eviction policies
|
||||||
* \ingroup CachedFactoryGroup
|
* \ingroup CachedFactoryGroup
|
||||||
|
@ -316,7 +317,7 @@ namespace Loki
|
||||||
typedef typename SwappedHitMap::iterator SwappedHitMapItr;
|
typedef typename SwappedHitMap::iterator SwappedHitMapItr;
|
||||||
protected:
|
protected:
|
||||||
HitMap m_mHitCount;
|
HitMap m_mHitCount;
|
||||||
|
|
||||||
// This function sorts the map according to the score
|
// This function sorts the map according to the score
|
||||||
// and returns the lower bound of the sorted container
|
// and returns the lower bound of the sorted container
|
||||||
DT& getLowerBound(){
|
DT& getLowerBound(){
|
||||||
|
@ -330,15 +331,15 @@ namespace Loki
|
||||||
return (*copyMap.begin()).second;
|
return (*copyMap.begin()).second;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \class EvictLRU
|
* \class EvictLRU
|
||||||
* \ingroup EvictionPolicyCachedFactoryGroup
|
* \ingroup EvictionPolicyCachedFactoryGroup
|
||||||
* \brief Evicts least accessed objects first.
|
* \brief Evicts least accessed objects first.
|
||||||
*
|
*
|
||||||
* Implementation of the Least recent used algorithm as
|
* Implementation of the Least recent used algorithm as
|
||||||
* described in http://en.wikipedia.org/wiki/Page_replacement_algorithms .
|
* described in http://en.wikipedia.org/wiki/Page_replacement_algorithms .
|
||||||
*
|
*
|
||||||
* WARNING : If an object is heavily fetched
|
* WARNING : If an object is heavily fetched
|
||||||
* (more than ULONG_MAX = UINT_MAX = 4294967295U)
|
* (more than ULONG_MAX = UINT_MAX = 4294967295U)
|
||||||
* it could unfortunately be removed from the cache.
|
* it could unfortunately be removed from the cache.
|
||||||
|
@ -353,20 +354,20 @@ namespace Loki
|
||||||
private:
|
private:
|
||||||
typedef EvictionHelper< ST , DT > EH;
|
typedef EvictionHelper< ST , DT > EH;
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
virtual ~EvictLRU(){}
|
virtual ~EvictLRU(){}
|
||||||
|
|
||||||
// OnStore initialize the counter for the new key
|
// OnStore initialize the counter for the new key
|
||||||
// If the key already exists, the counter is reseted
|
// If the key already exists, the counter is reseted
|
||||||
void onCreate(const DT& key)
|
void onCreate(const DT& key)
|
||||||
{
|
{
|
||||||
EH::m_mHitCount[key] = 0;
|
EH::m_mHitCount[key] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void onFetch(const DT&)
|
void onFetch(const DT&)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
// onRelease increments the hit counter associated with the object
|
// onRelease increments the hit counter associated with the object
|
||||||
void onRelease(const DT& key)
|
void onRelease(const DT& key)
|
||||||
{
|
{
|
||||||
|
@ -377,7 +378,7 @@ namespace Loki
|
||||||
{
|
{
|
||||||
EH::m_mHitCount.erase(key);
|
EH::m_mHitCount.erase(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
// this function is implemented in Cache and redirected
|
// this function is implemented in Cache and redirected
|
||||||
// to the Storage Policy
|
// to the Storage Policy
|
||||||
virtual void remove(DT const key)=0;
|
virtual void remove(DT const key)=0;
|
||||||
|
@ -389,15 +390,15 @@ namespace Loki
|
||||||
}
|
}
|
||||||
const char* name(){return "LRU";}
|
const char* name(){return "LRU";}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \class EvictAging
|
* \class EvictAging
|
||||||
* \ingroup EvictionPolicyCachedFactoryGroup
|
* \ingroup EvictionPolicyCachedFactoryGroup
|
||||||
* \brief LRU aware of the time span of use
|
* \brief LRU aware of the time span of use
|
||||||
*
|
*
|
||||||
* Implementation of the Aging algorithm as
|
* Implementation of the Aging algorithm as
|
||||||
* described in http://en.wikipedia.org/wiki/Page_replacement_algorithms .
|
* described in http://en.wikipedia.org/wiki/Page_replacement_algorithms .
|
||||||
*
|
*
|
||||||
* This method is much more costly than evict LRU so
|
* This method is much more costly than evict LRU so
|
||||||
* if you need extreme performance consider switching to EvictLRU
|
* if you need extreme performance consider switching to EvictLRU
|
||||||
*/
|
*/
|
||||||
|
@ -414,7 +415,7 @@ namespace Loki
|
||||||
typedef EvictionHelper< ST, DT > EH;
|
typedef EvictionHelper< ST, DT > EH;
|
||||||
typedef typename EH::HitMap HitMap;
|
typedef typename EH::HitMap HitMap;
|
||||||
typedef typename EH::HitMapItr HitMapItr;
|
typedef typename EH::HitMapItr HitMapItr;
|
||||||
|
|
||||||
// update the counter
|
// update the counter
|
||||||
template<class T> struct updateCounter : public std::unary_function<T, void>
|
template<class T> struct updateCounter : public std::unary_function<T, void>
|
||||||
{
|
{
|
||||||
|
@ -432,15 +433,15 @@ namespace Loki
|
||||||
protected:
|
protected:
|
||||||
EvictAging(){}
|
EvictAging(){}
|
||||||
virtual ~EvictAging(){}
|
virtual ~EvictAging(){}
|
||||||
|
|
||||||
// OnStore initialize the counter for the new key
|
// OnStore initialize the counter for the new key
|
||||||
// If the key already exists, the counter is reseted
|
// If the key already exists, the counter is reseted
|
||||||
void onCreate(const DT& key){
|
void onCreate(const DT& key){
|
||||||
EH::m_mHitCount[key] = 0;
|
EH::m_mHitCount[key] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void onFetch(const DT&){}
|
void onFetch(const DT&){}
|
||||||
|
|
||||||
// onRelease increments the hit counter associated with the object
|
// onRelease increments the hit counter associated with the object
|
||||||
// Updating every counters by iterating over the map
|
// Updating every counters by iterating over the map
|
||||||
// If the key is the key of the fetched object :
|
// If the key is the key of the fetched object :
|
||||||
|
@ -451,7 +452,7 @@ namespace Loki
|
||||||
{
|
{
|
||||||
std::for_each(EH::m_mHitCount.begin(), EH::m_mHitCount.end(), updateCounter< typename HitMap::value_type >(key));
|
std::for_each(EH::m_mHitCount.begin(), EH::m_mHitCount.end(), updateCounter< typename HitMap::value_type >(key));
|
||||||
}
|
}
|
||||||
|
|
||||||
void onDestroy(const DT& key)
|
void onDestroy(const DT& key)
|
||||||
{
|
{
|
||||||
EH::m_mHitCount.erase(key);
|
EH::m_mHitCount.erase(key);
|
||||||
|
@ -468,12 +469,12 @@ namespace Loki
|
||||||
}
|
}
|
||||||
const char* name(){return "LRU with aging";}
|
const char* name(){return "LRU with aging";}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \class EvictRandom
|
* \class EvictRandom
|
||||||
* \ingroup EvictionPolicyCachedFactoryGroup
|
* \ingroup EvictionPolicyCachedFactoryGroup
|
||||||
* \brief Evicts a random object
|
* \brief Evicts a random object
|
||||||
*
|
*
|
||||||
* Implementation of the Random algorithm as
|
* Implementation of the Random algorithm as
|
||||||
* described in http://en.wikipedia.org/wiki/Page_replacement_algorithms .
|
* described in http://en.wikipedia.org/wiki/Page_replacement_algorithms .
|
||||||
*/
|
*/
|
||||||
|
@ -490,24 +491,24 @@ namespace Loki
|
||||||
typedef typename std::vector< DT >::iterator iterator;
|
typedef typename std::vector< DT >::iterator iterator;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
virtual ~EvictRandom(){}
|
virtual ~EvictRandom(){}
|
||||||
|
|
||||||
void onCreate(const DT&){
|
void onCreate(const DT&){
|
||||||
}
|
}
|
||||||
|
|
||||||
void onFetch(const DT& ){
|
void onFetch(const DT& ){
|
||||||
}
|
}
|
||||||
|
|
||||||
void onRelease(const DT& key){
|
void onRelease(const DT& key){
|
||||||
m_vKeys.push_back(key);
|
m_vKeys.push_back(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
void onDestroy(const DT& key){
|
void onDestroy(const DT& key){
|
||||||
using namespace std;
|
using namespace std;
|
||||||
m_vKeys.erase(remove_if(m_vKeys.begin(), m_vKeys.end(), bind2nd(equal_to< DT >(), key)), m_vKeys.end());
|
m_vKeys.erase(remove_if(m_vKeys.begin(), m_vKeys.end(), bind2nd(equal_to< DT >(), key)), m_vKeys.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implemented in Cache and redirected to the Storage Policy
|
// Implemented in Cache and redirected to the Storage Policy
|
||||||
virtual void remove(DT const key)=0;
|
virtual void remove(DT const key)=0;
|
||||||
|
|
||||||
|
@ -526,7 +527,7 @@ namespace Loki
|
||||||
* \defgroup StatisticPolicyCachedFactoryGroup Statistic policies
|
* \defgroup StatisticPolicyCachedFactoryGroup Statistic policies
|
||||||
* \ingroup CachedFactoryGroup
|
* \ingroup CachedFactoryGroup
|
||||||
* \brief Gathers information about the cache.
|
* \brief Gathers information about the cache.
|
||||||
*
|
*
|
||||||
* For debugging purpose this policy proposes to gather informations
|
* For debugging purpose this policy proposes to gather informations
|
||||||
* about the cache. This could be useful to determine whether the cache is
|
* about the cache. This could be useful to determine whether the cache is
|
||||||
* mandatory or if the policies are well suited to the application.
|
* mandatory or if the policies are well suited to the application.
|
||||||
|
@ -536,7 +537,7 @@ namespace Loki
|
||||||
* \ingroup StatisticPolicyCachedFactoryGroup
|
* \ingroup StatisticPolicyCachedFactoryGroup
|
||||||
* \brief Do nothing
|
* \brief Do nothing
|
||||||
*
|
*
|
||||||
* Should be used in release code for better performances
|
* Should be used in release code for better performances
|
||||||
*/
|
*/
|
||||||
class NoStatisticPolicy
|
class NoStatisticPolicy
|
||||||
{
|
{
|
||||||
|
@ -548,7 +549,7 @@ namespace Loki
|
||||||
void onDestroy(){}
|
void onDestroy(){}
|
||||||
const char* name(){return "no";}
|
const char* name(){return "no";}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \class SimpleStatisticPolicy
|
* \class SimpleStatisticPolicy
|
||||||
* \ingroup StatisticPolicyCachedFactoryGroup
|
* \ingroup StatisticPolicyCachedFactoryGroup
|
||||||
|
@ -572,7 +573,7 @@ namespace Loki
|
||||||
SimpleStatisticPolicy() : allocated(0), created(0), hit(0), out(0), fetched(0)
|
SimpleStatisticPolicy() : allocated(0), created(0), hit(0), out(0), fetched(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void onDebug()
|
void onDebug()
|
||||||
{
|
{
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
@ -592,7 +593,7 @@ namespace Loki
|
||||||
}
|
}
|
||||||
cout << endl;
|
cout << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void onFetch()
|
void onFetch()
|
||||||
{
|
{
|
||||||
++fetched;
|
++fetched;
|
||||||
|
@ -623,8 +624,8 @@ namespace Loki
|
||||||
unsigned getAllocated(){return allocated;}
|
unsigned getAllocated(){return allocated;}
|
||||||
unsigned getOut(){return out;}
|
unsigned getOut(){return out;}
|
||||||
unsigned getDestroyed(){return created-allocated;}
|
unsigned getDestroyed(){return created-allocated;}
|
||||||
};
|
};
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// Cache Factory definition
|
// Cache Factory definition
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -633,16 +634,16 @@ namespace Loki
|
||||||
public:
|
public:
|
||||||
const char* what() const throw() { return "Internal Cache Error"; }
|
const char* what() const throw() { return "Internal Cache Error"; }
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \class CachedFactory
|
* \class CachedFactory
|
||||||
* \ingroup CachedFactoryGroup
|
* \ingroup CachedFactoryGroup
|
||||||
* \brief Factory with caching support
|
* \brief Factory with caching support
|
||||||
*
|
*
|
||||||
* This class acts as a Factory (it creates objects)
|
* This class acts as a Factory (it creates objects)
|
||||||
* but also keeps the already created objects to prevent
|
* but also keeps the already created objects to prevent
|
||||||
* long constructions time.
|
* long constructions time.
|
||||||
*
|
*
|
||||||
* Note this implementation do not retain ownership.
|
* Note this implementation do not retain ownership.
|
||||||
*/
|
*/
|
||||||
template
|
template
|
||||||
|
@ -657,7 +658,7 @@ namespace Loki
|
||||||
template<typename, class> class FactoryErrorPolicy = DefaultFactoryError,
|
template<typename, class> class FactoryErrorPolicy = DefaultFactoryError,
|
||||||
class ObjVector = std::vector<AbstractProduct*>
|
class ObjVector = std::vector<AbstractProduct*>
|
||||||
>
|
>
|
||||||
class CachedFactory :
|
class CachedFactory :
|
||||||
protected EncapsulationPolicy<AbstractProduct>,
|
protected EncapsulationPolicy<AbstractProduct>,
|
||||||
public CreationPolicy, public StatisticPolicy, EvictionPolicy< AbstractProduct * , unsigned >
|
public CreationPolicy, public StatisticPolicy, EvictionPolicy< AbstractProduct * , unsigned >
|
||||||
{
|
{
|
||||||
|
@ -669,7 +670,7 @@ namespace Loki
|
||||||
typedef CreationPolicy CP;
|
typedef CreationPolicy CP;
|
||||||
typedef StatisticPolicy SP;
|
typedef StatisticPolicy SP;
|
||||||
typedef EvictionPolicy< AbstractProduct* , unsigned > EP;
|
typedef EvictionPolicy< AbstractProduct* , unsigned > EP;
|
||||||
|
|
||||||
typedef typename Impl::Parm1 Parm1;
|
typedef typename Impl::Parm1 Parm1;
|
||||||
typedef typename Impl::Parm2 Parm2;
|
typedef typename Impl::Parm2 Parm2;
|
||||||
typedef typename Impl::Parm3 Parm3;
|
typedef typename Impl::Parm3 Parm3;
|
||||||
|
@ -685,14 +686,14 @@ namespace Loki
|
||||||
typedef typename Impl::Parm13 Parm13;
|
typedef typename Impl::Parm13 Parm13;
|
||||||
typedef typename Impl::Parm14 Parm14;
|
typedef typename Impl::Parm14 Parm14;
|
||||||
typedef typename Impl::Parm15 Parm15;
|
typedef typename Impl::Parm15 Parm15;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef typename NP::ProductReturn ProductReturn;
|
typedef typename NP::ProductReturn ProductReturn;
|
||||||
private:
|
private:
|
||||||
typedef Key< Impl, IdentifierType > MyKey;
|
typedef Key< Impl, IdentifierType > MyKey;
|
||||||
typedef std::map< MyKey, ObjVector > KeyToObjVectorMap;
|
typedef std::map< MyKey, ObjVector > KeyToObjVectorMap;
|
||||||
typedef std::map< AbstractProduct*, MyKey > FetchedObjToKeyMap;
|
typedef std::map< AbstractProduct*, MyKey > FetchedObjToKeyMap;
|
||||||
|
|
||||||
MyFactory factory;
|
MyFactory factory;
|
||||||
KeyToObjVectorMap fromKeyToObjVector;
|
KeyToObjVectorMap fromKeyToObjVector;
|
||||||
FetchedObjToKeyMap providedObjects;
|
FetchedObjToKeyMap providedObjects;
|
||||||
|
@ -702,7 +703,7 @@ namespace Loki
|
||||||
return fromKeyToObjVector[key];
|
return fromKeyToObjVector[key];
|
||||||
}
|
}
|
||||||
|
|
||||||
AbstractProduct* const getPointerToObjectInContainer(ObjVector &entry)
|
AbstractProduct* getPointerToObjectInContainer(ObjVector &entry)
|
||||||
{
|
{
|
||||||
if(entry.empty()) // No object available
|
if(entry.empty()) // No object available
|
||||||
{ // the object will be created in the calling function.
|
{ // the object will be created in the calling function.
|
||||||
|
@ -718,7 +719,7 @@ namespace Loki
|
||||||
return pObject;
|
return pObject;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool shouldCreateObject(AbstractProduct * const pProduct){
|
bool shouldCreateObject(AbstractProduct * const pProduct){
|
||||||
if(pProduct!=NULL) // object already exists
|
if(pProduct!=NULL) // object already exists
|
||||||
return false;
|
return false;
|
||||||
|
@ -726,40 +727,40 @@ namespace Loki
|
||||||
EP::evict(); // calling Eviction Policy to clean up
|
EP::evict(); // calling Eviction Policy to clean up
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReleaseObjectFromContainer(ObjVector &entry, AbstractProduct * const object)
|
void ReleaseObjectFromContainer(ObjVector &entry, AbstractProduct * const object)
|
||||||
{
|
{
|
||||||
entry.push_back(object);
|
entry.push_back(object);
|
||||||
}
|
}
|
||||||
|
|
||||||
void onFetch(AbstractProduct * const pProduct)
|
void onFetch(AbstractProduct * const pProduct)
|
||||||
{
|
{
|
||||||
SP::onFetch();
|
SP::onFetch();
|
||||||
EP::onFetch(pProduct);
|
EP::onFetch(pProduct);
|
||||||
++outObjects;
|
++outObjects;
|
||||||
}
|
}
|
||||||
|
|
||||||
void onRelease(AbstractProduct * const pProduct)
|
void onRelease(AbstractProduct * const pProduct)
|
||||||
{
|
{
|
||||||
SP::onRelease();
|
SP::onRelease();
|
||||||
EP::onRelease(pProduct);
|
EP::onRelease(pProduct);
|
||||||
--outObjects;
|
--outObjects;
|
||||||
}
|
}
|
||||||
|
|
||||||
void onCreate(AbstractProduct * const pProduct)
|
void onCreate(AbstractProduct * const pProduct)
|
||||||
{
|
{
|
||||||
CP::onCreate();
|
CP::onCreate();
|
||||||
SP::onCreate();
|
SP::onCreate();
|
||||||
EP::onCreate(pProduct);
|
EP::onCreate(pProduct);
|
||||||
}
|
}
|
||||||
|
|
||||||
void onDestroy(AbstractProduct * const pProduct)
|
void onDestroy(AbstractProduct * const pProduct)
|
||||||
{
|
{
|
||||||
CP::onDestroy();
|
CP::onDestroy();
|
||||||
SP::onDestroy();
|
SP::onDestroy();
|
||||||
EP::onDestroy(pProduct);
|
EP::onDestroy(pProduct);
|
||||||
}
|
}
|
||||||
|
|
||||||
// delete the object
|
// delete the object
|
||||||
template<class T> struct deleteObject : public std::unary_function<T, void>
|
template<class T> struct deleteObject : public std::unary_function<T, void>
|
||||||
{
|
{
|
||||||
|
@ -779,7 +780,7 @@ namespace Loki
|
||||||
template<class T> struct deleteMapKeys : public std::unary_function<T, void>
|
template<class T> struct deleteMapKeys : public std::unary_function<T, void>
|
||||||
{
|
{
|
||||||
void operator()(T x){ delete x.first; }
|
void operator()(T x){ delete x.first; }
|
||||||
};
|
};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void remove(AbstractProduct * const pProduct)
|
virtual void remove(AbstractProduct * const pProduct)
|
||||||
|
@ -834,23 +835,23 @@ namespace Loki
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////
|
///////////////////////////////////
|
||||||
// Acts as the proxy pattern and //
|
// Acts as the proxy pattern and //
|
||||||
// forwards factory methods //
|
// forwards factory methods //
|
||||||
///////////////////////////////////
|
///////////////////////////////////
|
||||||
|
|
||||||
bool Register(const IdentifierType& id, ProductCreator creator)
|
bool Register(const IdentifierType& id, ProductCreator creator)
|
||||||
{
|
{
|
||||||
return factory.Register(id, creator);
|
return factory.Register(id, creator);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class PtrObj, typename CreaFn>
|
template <class PtrObj, typename CreaFn>
|
||||||
bool Register(const IdentifierType& id, const PtrObj& p, CreaFn fn)
|
bool Register(const IdentifierType& id, const PtrObj& p, CreaFn fn)
|
||||||
{
|
{
|
||||||
return factory.Register(id, p, fn);
|
return factory.Register(id, p, fn);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Unregister(const IdentifierType& id)
|
bool Unregister(const IdentifierType& id)
|
||||||
{
|
{
|
||||||
return factory.Unregister(id);
|
return factory.Unregister(id);
|
||||||
|
@ -875,7 +876,7 @@ namespace Loki
|
||||||
providedObjects[pProduct] = key;
|
providedObjects[pProduct] = key;
|
||||||
return NP::encapsulate(pProduct);
|
return NP::encapsulate(pProduct);
|
||||||
}
|
}
|
||||||
|
|
||||||
ProductReturn CreateObject(const IdentifierType& id,
|
ProductReturn CreateObject(const IdentifierType& id,
|
||||||
Parm1 p1)
|
Parm1 p1)
|
||||||
{
|
{
|
||||||
|
@ -1020,7 +1021,7 @@ namespace Loki
|
||||||
providedObjects[pProduct] = key;
|
providedObjects[pProduct] = key;
|
||||||
return NP::encapsulate(pProduct);
|
return NP::encapsulate(pProduct);
|
||||||
}
|
}
|
||||||
|
|
||||||
ProductReturn CreateObject(const IdentifierType& id,
|
ProductReturn CreateObject(const IdentifierType& id,
|
||||||
Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
|
Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
|
||||||
Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9,Parm10 p10)
|
Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9,Parm10 p10)
|
||||||
|
@ -1147,7 +1148,7 @@ namespace Loki
|
||||||
ReleaseObjectFromContainer(getContainerFromKey((*itr).second), pProduct);
|
ReleaseObjectFromContainer(getContainerFromKey((*itr).second), pProduct);
|
||||||
providedObjects.erase(itr);
|
providedObjects.erase(itr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// display the cache configuration
|
/// display the cache configuration
|
||||||
void displayCacheType()
|
void displayCacheType()
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Reference in a new issue