add CachedFactory, initial version of Guillaume Chatelet
git-svn-id: svn://svn.code.sf.net/p/loki-lib/code/trunk@719 7ec92016-0320-0410-acc4-a06ded1c099a
This commit is contained in:
parent
530af30626
commit
cf3ca512e6
7 changed files with 2467 additions and 0 deletions
1040
include/loki/CachedFactory.h
Executable file
1040
include/loki/CachedFactory.h
Executable file
File diff suppressed because it is too large
Load diff
743
include/loki/Key.h
Executable file
743
include/loki/Key.h
Executable file
|
@ -0,0 +1,743 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// The Loki Library
|
||||
// Copyright (c) 2006 by Guillaume Chatelet
|
||||
//
|
||||
// Code covered by the MIT License
|
||||
//
|
||||
// Permission to use, copy, modify, distribute and sell this software for any
|
||||
// purpose is hereby granted without fee, provided that the above copyright
|
||||
// notice appear in all copies and that both that copyright notice and this
|
||||
// permission notice appear in supporting documentation.
|
||||
//
|
||||
// The authors make no representations about the suitability of this software
|
||||
// for any purpose. It is provided "as is" without express or implied warranty.
|
||||
//
|
||||
// This code DOES NOT accompany the book:
|
||||
// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
|
||||
// Patterns Applied". Copyright (c) 2001. Addison-Wesley.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _KEY_H_
|
||||
#define _KEY_H_
|
||||
|
||||
#include <loki/Factory.h>
|
||||
|
||||
namespace Loki
|
||||
{
|
||||
/*
|
||||
* A Key class
|
||||
*/
|
||||
template<
|
||||
class Factory,
|
||||
typename IdentifierType
|
||||
>
|
||||
class Key
|
||||
{
|
||||
typedef typename Factory::Parm1 Parm1;
|
||||
typedef typename Factory::Parm2 Parm2;
|
||||
typedef typename Factory::Parm3 Parm3;
|
||||
typedef typename Factory::Parm4 Parm4;
|
||||
typedef typename Factory::Parm5 Parm5;
|
||||
typedef typename Factory::Parm6 Parm6;
|
||||
typedef typename Factory::Parm7 Parm7;
|
||||
typedef typename Factory::Parm8 Parm8;
|
||||
typedef typename Factory::Parm9 Parm9;
|
||||
typedef typename Factory::Parm10 Parm10;
|
||||
typedef typename Factory::Parm11 Parm11;
|
||||
typedef typename Factory::Parm12 Parm12;
|
||||
typedef typename Factory::Parm13 Parm13;
|
||||
typedef typename Factory::Parm14 Parm14;
|
||||
typedef typename Factory::Parm15 Parm15;
|
||||
public:
|
||||
// member variables
|
||||
int count; // should be const, but constness prevent default copy ctor
|
||||
IdentifierType id;
|
||||
Parm1 p1;
|
||||
Parm2 p2;
|
||||
Parm3 p3;
|
||||
Parm4 p4;
|
||||
Parm5 p5;
|
||||
Parm6 p6;
|
||||
Parm7 p7;
|
||||
Parm8 p8;
|
||||
Parm9 p9;
|
||||
Parm10 p10;
|
||||
Parm11 p11;
|
||||
Parm12 p12;
|
||||
Parm13 p13;
|
||||
Parm14 p14;
|
||||
Parm15 p15;
|
||||
|
||||
// member functions
|
||||
Key() : count(-1)
|
||||
{
|
||||
}
|
||||
|
||||
Key(const IdentifierType& id) : count(0)
|
||||
{
|
||||
this->id = id;
|
||||
}
|
||||
|
||||
Key(const IdentifierType& id,
|
||||
Parm1 &p1) : count(1)
|
||||
{
|
||||
this->id = id;
|
||||
this->p1 = p1;
|
||||
}
|
||||
|
||||
Key(const IdentifierType& id,
|
||||
Parm1 &p1, Parm2 &p2) : count(2)
|
||||
{
|
||||
this->id = id;
|
||||
this->p1 = p1;
|
||||
this->p2 = p2;
|
||||
}
|
||||
|
||||
Key(const IdentifierType& id,
|
||||
Parm1 &p1, Parm2 &p2, Parm3 &p3) : count(3)
|
||||
{
|
||||
this->id = id;
|
||||
this->p1 = p1;
|
||||
this->p2 = p2;
|
||||
this->p3 = p3;
|
||||
}
|
||||
|
||||
Key(const IdentifierType& id,
|
||||
Parm1 &p1, Parm2 &p2, Parm3 &p3, Parm4 &p4) : count(4)
|
||||
{
|
||||
this->id = id;
|
||||
this->p1 = p1;
|
||||
this->p2 = p2;
|
||||
this->p3 = p3;
|
||||
this->p4 = p4;
|
||||
}
|
||||
|
||||
Key(const IdentifierType& id,
|
||||
Parm1 &p1, Parm2 &p2, Parm3 &p3, Parm4 &p4, Parm5 &p5) : count(5)
|
||||
{
|
||||
this->id = id;
|
||||
this->p1 = p1;
|
||||
this->p2 = p2;
|
||||
this->p3 = p3;
|
||||
this->p4 = p4;
|
||||
this->p5 = p5;
|
||||
}
|
||||
|
||||
Key(const IdentifierType& id,
|
||||
Parm1 &p1, Parm2 &p2, Parm3 &p3, Parm4 &p4, Parm5 &p5,
|
||||
Parm6 &p6) : count(6)
|
||||
{
|
||||
this->id = id;
|
||||
this->p1 = p1;
|
||||
this->p2 = p2;
|
||||
this->p3 = p3;
|
||||
this->p4 = p4;
|
||||
this->p5 = p5;
|
||||
this->p6 = p6;
|
||||
}
|
||||
|
||||
Key(const IdentifierType& id,
|
||||
Parm1 &p1, Parm2 &p2, Parm3 &p3, Parm4 &p4, Parm5 &p5,
|
||||
Parm6 &p6, Parm7 &p7 ) : count(7)
|
||||
{
|
||||
this->id = id;
|
||||
this->p1 = p1;
|
||||
this->p2 = p2;
|
||||
this->p3 = p3;
|
||||
this->p4 = p4;
|
||||
this->p5 = p5;
|
||||
this->p6 = p6;
|
||||
this->p7 = p7;
|
||||
}
|
||||
|
||||
Key(const IdentifierType& id,
|
||||
Parm1 &p1, Parm2 &p2, Parm3 &p3, Parm4 &p4, Parm5 &p5,
|
||||
Parm6 &p6, Parm7 &p7, Parm8 &p8) : count(8)
|
||||
{
|
||||
this->id = id;
|
||||
this->p1 = p1;
|
||||
this->p2 = p2;
|
||||
this->p3 = p3;
|
||||
this->p4 = p4;
|
||||
this->p5 = p5;
|
||||
this->p6 = p6;
|
||||
this->p7 = p7;
|
||||
this->p8 = p8;
|
||||
}
|
||||
|
||||
Key(const IdentifierType& id,
|
||||
Parm1 &p1, Parm2 &p2, Parm3 &p3, Parm4 &p4, Parm5 &p5,
|
||||
Parm6 &p6, Parm7 &p7, Parm8 &p8, Parm9 &p9) : count(9)
|
||||
{
|
||||
this->id = id;
|
||||
this->p1 = p1;
|
||||
this->p2 = p2;
|
||||
this->p3 = p3;
|
||||
this->p4 = p4;
|
||||
this->p5 = p5;
|
||||
this->p6 = p6;
|
||||
this->p7 = p7;
|
||||
this->p8 = p8;
|
||||
this->p9 = p9;
|
||||
}
|
||||
|
||||
Key(const IdentifierType& id,
|
||||
Parm1 &p1, Parm2 &p2, Parm3 &p3, Parm4 &p4, Parm5 &p5,
|
||||
Parm6 &p6, Parm7 &p7, Parm8 &p8, Parm9 &p9,Parm10 &p10) : count(10)
|
||||
{
|
||||
this->id = id;
|
||||
this->p1 = p1;
|
||||
this->p2 = p2;
|
||||
this->p3 = p3;
|
||||
this->p4 = p4;
|
||||
this->p5 = p5;
|
||||
this->p6 = p6;
|
||||
this->p7 = p7;
|
||||
this->p8 = p8;
|
||||
this->p9 = p9;
|
||||
this->p10 = p10;
|
||||
}
|
||||
|
||||
Key(const IdentifierType& id,
|
||||
Parm1 &p1, Parm2 &p2, Parm3 &p3, Parm4 &p4, Parm5 &p5,
|
||||
Parm6 &p6, Parm7 &p7, Parm8 &p8, Parm9 &p9, Parm10 &p10,
|
||||
Parm11 &p11) : count(11)
|
||||
{
|
||||
this->id = id;
|
||||
this->p1 = p1;
|
||||
this->p2 = p2;
|
||||
this->p3 = p3;
|
||||
this->p4 = p4;
|
||||
this->p5 = p5;
|
||||
this->p6 = p6;
|
||||
this->p7 = p7;
|
||||
this->p8 = p8;
|
||||
this->p9 = p9;
|
||||
this->p10 = p10;
|
||||
this->p11 = p11;
|
||||
}
|
||||
|
||||
Key(const IdentifierType& id,
|
||||
Parm1 &p1, Parm2 &p2, Parm3 &p3, Parm4 &p4, Parm5 &p5,
|
||||
Parm6 &p6, Parm7 &p7, Parm8 &p8, Parm9 &p9, Parm10 &p10,
|
||||
Parm11 &p11, Parm12 &p12) : count(12)
|
||||
{
|
||||
this->id = id;
|
||||
this->p1 = p1;
|
||||
this->p2 = p2;
|
||||
this->p3 = p3;
|
||||
this->p4 = p4;
|
||||
this->p5 = p5;
|
||||
this->p6 = p6;
|
||||
this->p7 = p7;
|
||||
this->p8 = p8;
|
||||
this->p9 = p9;
|
||||
this->p10 = p10;
|
||||
this->p11 = p11;
|
||||
this->p12 = p12;
|
||||
}
|
||||
|
||||
Key(const IdentifierType& id,
|
||||
Parm1 &p1, Parm2 &p2, Parm3 &p3, Parm4 &p4, Parm5 &p5,
|
||||
Parm6 &p6, Parm7 &p7, Parm8 &p8, Parm9 &p9, Parm10 &p10,
|
||||
Parm11 &p11, Parm12 &p12, Parm13 &p13) : count(13)
|
||||
{
|
||||
this->id = id;
|
||||
this->p1 = p1;
|
||||
this->p2 = p2;
|
||||
this->p3 = p3;
|
||||
this->p4 = p4;
|
||||
this->p5 = p5;
|
||||
this->p6 = p6;
|
||||
this->p7 = p7;
|
||||
this->p8 = p8;
|
||||
this->p9 = p9;
|
||||
this->p10 = p10;
|
||||
this->p11 = p11;
|
||||
this->p12 = p12;
|
||||
this->p13 = p13;
|
||||
}
|
||||
|
||||
Key(const IdentifierType& id,
|
||||
Parm1 &p1, Parm2 &p2, Parm3 &p3, Parm4 &p4, Parm5 &p5,
|
||||
Parm6 &p6, Parm7 &p7, Parm8 &p8, Parm9 &p9, Parm10 &p10,
|
||||
Parm11 &p11, Parm12 &p12, Parm13 &p13, Parm14 &p14) : count(14)
|
||||
{
|
||||
this->id = id;
|
||||
this->p1 = p1;
|
||||
this->p2 = p2;
|
||||
this->p3 = p3;
|
||||
this->p4 = p4;
|
||||
this->p5 = p5;
|
||||
this->p6 = p6;
|
||||
this->p7 = p7;
|
||||
this->p8 = p8;
|
||||
this->p9 = p9;
|
||||
this->p10 = p10;
|
||||
this->p11 = p11;
|
||||
this->p12 = p12;
|
||||
this->p13 = p13;
|
||||
this->p14 = p14;
|
||||
}
|
||||
|
||||
Key(const IdentifierType& id,
|
||||
Parm1 &p1, Parm2 &p2, Parm3 &p3, Parm4 &p4, Parm5 &p5,
|
||||
Parm6 &p6, Parm7 &p7, Parm8 &p8, Parm9 &p9, Parm10 &p10,
|
||||
Parm11 &p11, Parm12 &p12, Parm13 &p13, Parm14 &p14, Parm15 &p15) : count(15)
|
||||
{
|
||||
this->id = id;
|
||||
this->p1 = p1;
|
||||
this->p2 = p2;
|
||||
this->p3 = p3;
|
||||
this->p4 = p4;
|
||||
this->p5 = p5;
|
||||
this->p6 = p6;
|
||||
this->p7 = p7;
|
||||
this->p8 = p8;
|
||||
this->p9 = p9;
|
||||
this->p10 = p10;
|
||||
this->p11 = p11;
|
||||
this->p12 = p12;
|
||||
this->p13 = p13;
|
||||
this->p14 = p14;
|
||||
this->p15 = p15;
|
||||
}
|
||||
|
||||
friend bool operator==(const EmptyType &k1, const EmptyType &k2)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
friend bool operator==(const Key &k1, const Key &k2)
|
||||
{
|
||||
if( k1.count != k2.count )
|
||||
return false;
|
||||
switch(k1.count){
|
||||
case -1:
|
||||
return true;
|
||||
case 0:
|
||||
if( k1.id == k2.id )
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
case 1:
|
||||
if( (k1.id == k2.id) &&
|
||||
(k1.p1 == k2.p1) )
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
case 2:
|
||||
if( (k1.id == k2.id) &&
|
||||
(k1.p1 == k2.p1) &&
|
||||
(k1.p2 == k2.p2) )
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
case 3:
|
||||
if( (k1.id == k2.id) &&
|
||||
(k1.p1 == k2.p1) &&
|
||||
(k1.p2 == k2.p2) &&
|
||||
(k1.p3 == k2.p3) )
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
case 4:
|
||||
if( (k1.id == k2.id) &&
|
||||
(k1.p1 == k2.p1) &&
|
||||
(k1.p2 == k2.p2) &&
|
||||
(k1.p3 == k2.p3) &&
|
||||
(k1.p4 == k2.p4) )
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
case 5:
|
||||
if( (k1.id == k2.id) &&
|
||||
(k1.p1 == k2.p1) &&
|
||||
(k1.p2 == k2.p2) &&
|
||||
(k1.p3 == k2.p3) &&
|
||||
(k1.p4 == k2.p4) &&
|
||||
(k1.p5 == k2.p5) )
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
case 6:
|
||||
if( (k1.id == k2.id) &&
|
||||
(k1.p1 == k2.p1) &&
|
||||
(k1.p2 == k2.p2) &&
|
||||
(k1.p3 == k2.p3) &&
|
||||
(k1.p4 == k2.p4) &&
|
||||
(k1.p5 == k2.p5) &&
|
||||
(k1.p6 == k2.p6) )
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
case 7:
|
||||
if( (k1.id == k2.id) &&
|
||||
(k1.p1 == k2.p1) &&
|
||||
(k1.p2 == k2.p2) &&
|
||||
(k1.p3 == k2.p3) &&
|
||||
(k1.p4 == k2.p4) &&
|
||||
(k1.p5 == k2.p5) &&
|
||||
(k1.p6 == k2.p6) &&
|
||||
(k1.p7 == k2.p7) )
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
case 8:
|
||||
if( (k1.id == k2.id) &&
|
||||
(k1.p1 == k2.p1) &&
|
||||
(k1.p2 == k2.p2) &&
|
||||
(k1.p3 == k2.p3) &&
|
||||
(k1.p4 == k2.p4) &&
|
||||
(k1.p5 == k2.p5) &&
|
||||
(k1.p6 == k2.p6) &&
|
||||
(k1.p7 == k2.p7) &&
|
||||
(k1.p8 == k2.p8) )
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
case 9:
|
||||
if( (k1.id == k2.id) &&
|
||||
(k1.p1 == k2.p1) &&
|
||||
(k1.p2 == k2.p2) &&
|
||||
(k1.p3 == k2.p3) &&
|
||||
(k1.p4 == k2.p4) &&
|
||||
(k1.p5 == k2.p5) &&
|
||||
(k1.p6 == k2.p6) &&
|
||||
(k1.p7 == k2.p7) &&
|
||||
(k1.p8 == k2.p8) &&
|
||||
(k1.p9 == k2.p9) )
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
case 10:
|
||||
if( (k1.id == k2.id) &&
|
||||
(k1.p1 == k2.p1) &&
|
||||
(k1.p2 == k2.p2) &&
|
||||
(k1.p3 == k2.p3) &&
|
||||
(k1.p4 == k2.p4) &&
|
||||
(k1.p5 == k2.p5) &&
|
||||
(k1.p6 == k2.p6) &&
|
||||
(k1.p7 == k2.p7) &&
|
||||
(k1.p8 == k2.p8) &&
|
||||
(k1.p9 == k2.p9) &&
|
||||
(k1.p10 == k2.p10) )
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
case 11:
|
||||
if( (k1.id == k2.id) &&
|
||||
(k1.p1 == k2.p1) &&
|
||||
(k1.p2 == k2.p2) &&
|
||||
(k1.p3 == k2.p3) &&
|
||||
(k1.p4 == k2.p4) &&
|
||||
(k1.p5 == k2.p5) &&
|
||||
(k1.p6 == k2.p6) &&
|
||||
(k1.p7 == k2.p7) &&
|
||||
(k1.p8 == k2.p8) &&
|
||||
(k1.p9 == k2.p9) &&
|
||||
(k1.p10 == k2.p10) &&
|
||||
(k1.p11 == k2.p11) )
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
case 12:
|
||||
if( (k1.id == k2.id) &&
|
||||
(k1.p1 == k2.p1) &&
|
||||
(k1.p2 == k2.p2) &&
|
||||
(k1.p3 == k2.p3) &&
|
||||
(k1.p4 == k2.p4) &&
|
||||
(k1.p5 == k2.p5) &&
|
||||
(k1.p6 == k2.p6) &&
|
||||
(k1.p7 == k2.p7) &&
|
||||
(k1.p8 == k2.p8) &&
|
||||
(k1.p9 == k2.p9) &&
|
||||
(k1.p10 == k2.p10) &&
|
||||
(k1.p11 == k2.p11) &&
|
||||
(k1.p12 == k2.p12) )
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
case 13:
|
||||
if( (k1.id == k2.id) &&
|
||||
(k1.p1 == k2.p1) &&
|
||||
(k1.p2 == k2.p2) &&
|
||||
(k1.p3 == k2.p3) &&
|
||||
(k1.p4 == k2.p4) &&
|
||||
(k1.p5 == k2.p5) &&
|
||||
(k1.p6 == k2.p6) &&
|
||||
(k1.p7 == k2.p7) &&
|
||||
(k1.p8 == k2.p8) &&
|
||||
(k1.p9 == k2.p9) &&
|
||||
(k1.p10 == k2.p10) &&
|
||||
(k1.p11 == k2.p11) &&
|
||||
(k1.p12 == k2.p12) &&
|
||||
(k1.p13 == k2.p13) )
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
case 14:
|
||||
if( (k1.id == k2.id) &&
|
||||
(k1.p1 == k2.p1) &&
|
||||
(k1.p2 == k2.p2) &&
|
||||
(k1.p3 == k2.p3) &&
|
||||
(k1.p4 == k2.p4) &&
|
||||
(k1.p5 == k2.p5) &&
|
||||
(k1.p6 == k2.p6) &&
|
||||
(k1.p7 == k2.p7) &&
|
||||
(k1.p8 == k2.p8) &&
|
||||
(k1.p9 == k2.p9) &&
|
||||
(k1.p10 == k2.p10) &&
|
||||
(k1.p11 == k2.p11) &&
|
||||
(k1.p12 == k2.p12) &&
|
||||
(k1.p13 == k2.p13) &&
|
||||
(k1.p14 == k2.p14) )
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
case 15:
|
||||
if( (k1.id == k2.id) &&
|
||||
(k1.p1 == k2.p1) &&
|
||||
(k1.p2 == k2.p2) &&
|
||||
(k1.p3 == k2.p3) &&
|
||||
(k1.p4 == k2.p4) &&
|
||||
(k1.p5 == k2.p5) &&
|
||||
(k1.p6 == k2.p6) &&
|
||||
(k1.p7 == k2.p7) &&
|
||||
(k1.p8 == k2.p8) &&
|
||||
(k1.p9 == k2.p9) &&
|
||||
(k1.p10 == k2.p10) &&
|
||||
(k1.p11 == k2.p11) &&
|
||||
(k1.p12 == k2.p12) &&
|
||||
(k1.p13 == k2.p13) &&
|
||||
(k1.p14 == k2.p14) &&
|
||||
(k1.p15 == k2.p15) )
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
friend bool operator<(const EmptyType &k1, const EmptyType &k2)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
friend bool operator<(const Key &k1, const Key &k2)
|
||||
{
|
||||
if( k1.count < k2.count )
|
||||
return true;
|
||||
switch(k1.count){
|
||||
case -1:
|
||||
return false;
|
||||
case 0:
|
||||
if( k1.id < k2.id )
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
case 1:
|
||||
if( (k1.id < k2.id) ||
|
||||
(k1.p1 < k2.p1) )
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
case 2:
|
||||
if( (k1.id < k2.id) ||
|
||||
(k1.p1 < k2.p1) ||
|
||||
(k1.p2 < k2.p2) )
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
case 3:
|
||||
if( (k1.id < k2.id) ||
|
||||
(k1.p1 < k2.p1) ||
|
||||
(k1.p2 < k2.p2) ||
|
||||
(k1.p3 < k2.p3) )
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
case 4:
|
||||
if( (k1.id < k2.id) ||
|
||||
(k1.p1 < k2.p1) ||
|
||||
(k1.p2 < k2.p2) ||
|
||||
(k1.p3 < k2.p3) ||
|
||||
(k1.p4 < k2.p4) )
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
case 5:
|
||||
if( (k1.id < k2.id) ||
|
||||
(k1.p1 < k2.p1) ||
|
||||
(k1.p2 < k2.p2) ||
|
||||
(k1.p3 < k2.p3) ||
|
||||
(k1.p4 < k2.p4) ||
|
||||
(k1.p5 < k2.p5) )
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
case 6:
|
||||
if( (k1.id < k2.id) ||
|
||||
(k1.p1 < k2.p1) ||
|
||||
(k1.p2 < k2.p2) ||
|
||||
(k1.p3 < k2.p3) ||
|
||||
(k1.p4 < k2.p4) ||
|
||||
(k1.p5 < k2.p5) ||
|
||||
(k1.p6 < k2.p6) )
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
case 7:
|
||||
if( (k1.id < k2.id) ||
|
||||
(k1.p1 < k2.p1) ||
|
||||
(k1.p2 < k2.p2) ||
|
||||
(k1.p3 < k2.p3) ||
|
||||
(k1.p4 < k2.p4) ||
|
||||
(k1.p5 < k2.p5) ||
|
||||
(k1.p6 < k2.p6) ||
|
||||
(k1.p7 < k2.p7) )
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
case 8:
|
||||
if( (k1.id < k2.id) ||
|
||||
(k1.p1 < k2.p1) ||
|
||||
(k1.p2 < k2.p2) ||
|
||||
(k1.p3 < k2.p3) ||
|
||||
(k1.p4 < k2.p4) ||
|
||||
(k1.p5 < k2.p5) ||
|
||||
(k1.p6 < k2.p6) ||
|
||||
(k1.p7 < k2.p7) ||
|
||||
(k1.p8 < k2.p8) )
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
case 9:
|
||||
if( (k1.id < k2.id) ||
|
||||
(k1.p1 < k2.p1) ||
|
||||
(k1.p2 < k2.p2) ||
|
||||
(k1.p3 < k2.p3) ||
|
||||
(k1.p4 < k2.p4) ||
|
||||
(k1.p5 < k2.p5) ||
|
||||
(k1.p6 < k2.p6) ||
|
||||
(k1.p7 < k2.p7) ||
|
||||
(k1.p8 < k2.p8) ||
|
||||
(k1.p9 < k2.p9) )
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
case 10:
|
||||
if( (k1.id < k2.id) ||
|
||||
(k1.p1 < k2.p1) ||
|
||||
(k1.p2 < k2.p2) ||
|
||||
(k1.p3 < k2.p3) ||
|
||||
(k1.p4 < k2.p4) ||
|
||||
(k1.p5 < k2.p5) ||
|
||||
(k1.p6 < k2.p6) ||
|
||||
(k1.p7 < k2.p7) ||
|
||||
(k1.p8 < k2.p8) ||
|
||||
(k1.p9 < k2.p9) ||
|
||||
(k1.p10 < k2.p10) )
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
case 11:
|
||||
if( (k1.id < k2.id) ||
|
||||
(k1.p1 < k2.p1) ||
|
||||
(k1.p2 < k2.p2) ||
|
||||
(k1.p3 < k2.p3) ||
|
||||
(k1.p4 < k2.p4) ||
|
||||
(k1.p5 < k2.p5) ||
|
||||
(k1.p6 < k2.p6) ||
|
||||
(k1.p7 < k2.p7) ||
|
||||
(k1.p8 < k2.p8) ||
|
||||
(k1.p9 < k2.p9) ||
|
||||
(k1.p10 < k2.p10) ||
|
||||
(k1.p11 < k2.p11) )
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
case 12:
|
||||
if( (k1.id < k2.id) ||
|
||||
(k1.p1 < k2.p1) ||
|
||||
(k1.p2 < k2.p2) ||
|
||||
(k1.p3 < k2.p3) ||
|
||||
(k1.p4 < k2.p4) ||
|
||||
(k1.p5 < k2.p5) ||
|
||||
(k1.p6 < k2.p6) ||
|
||||
(k1.p7 < k2.p7) ||
|
||||
(k1.p8 < k2.p8) ||
|
||||
(k1.p9 < k2.p9) ||
|
||||
(k1.p10 < k2.p10) ||
|
||||
(k1.p11 < k2.p11) ||
|
||||
(k1.p12 < k2.p12) )
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
case 13:
|
||||
if( (k1.id < k2.id) ||
|
||||
(k1.p1 < k2.p1) ||
|
||||
(k1.p2 < k2.p2) ||
|
||||
(k1.p3 < k2.p3) ||
|
||||
(k1.p4 < k2.p4) ||
|
||||
(k1.p5 < k2.p5) ||
|
||||
(k1.p6 < k2.p6) ||
|
||||
(k1.p7 < k2.p7) ||
|
||||
(k1.p8 < k2.p8) ||
|
||||
(k1.p9 < k2.p9) ||
|
||||
(k1.p10 < k2.p10) ||
|
||||
(k1.p11 < k2.p11) ||
|
||||
(k1.p12 < k2.p12) ||
|
||||
(k1.p13 < k2.p13) )
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
case 14:
|
||||
if( (k1.id < k2.id) ||
|
||||
(k1.p1 < k2.p1) ||
|
||||
(k1.p2 < k2.p2) ||
|
||||
(k1.p3 < k2.p3) ||
|
||||
(k1.p4 < k2.p4) ||
|
||||
(k1.p5 < k2.p5) ||
|
||||
(k1.p6 < k2.p6) ||
|
||||
(k1.p7 < k2.p7) ||
|
||||
(k1.p8 < k2.p8) ||
|
||||
(k1.p9 < k2.p9) ||
|
||||
(k1.p10 < k2.p10) ||
|
||||
(k1.p11 < k2.p11) ||
|
||||
(k1.p12 < k2.p12) ||
|
||||
(k1.p13 < k2.p13) ||
|
||||
(k1.p14 < k2.p14) )
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
case 15:
|
||||
if( (k1.id < k2.id) ||
|
||||
(k1.p1 < k2.p1) ||
|
||||
(k1.p2 < k2.p2) ||
|
||||
(k1.p3 < k2.p3) ||
|
||||
(k1.p4 < k2.p4) ||
|
||||
(k1.p5 < k2.p5) ||
|
||||
(k1.p6 < k2.p6) ||
|
||||
(k1.p7 < k2.p7) ||
|
||||
(k1.p8 < k2.p8) ||
|
||||
(k1.p9 < k2.p9) ||
|
||||
(k1.p10 < k2.p10) ||
|
||||
(k1.p11 < k2.p11) ||
|
||||
(k1.p12 < k2.p12) ||
|
||||
(k1.p13 < k2.p13) ||
|
||||
(k1.p14 < k2.p14) ||
|
||||
(k1.p15 < k2.p15) )
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
} // namespace Loki
|
||||
|
||||
#endif /*_KEY_H_*/
|
61
test/CachedFactory/CachedFactory.dev
Executable file
61
test/CachedFactory/CachedFactory.dev
Executable file
|
@ -0,0 +1,61 @@
|
|||
[Project]
|
||||
FileName=CachedFactory.dev
|
||||
Name=Factory
|
||||
UnitCount=2
|
||||
Type=1
|
||||
Ver=1
|
||||
ObjFiles=
|
||||
Includes=..\..\include
|
||||
Libs=
|
||||
PrivateResource=
|
||||
ResourceIncludes=
|
||||
MakeIncludes=
|
||||
Compiler=
|
||||
CppCompiler=-D DEBUG_@@_-D _DEBUG_@@_-Wall -pedantic_@@_
|
||||
Linker=
|
||||
IsCpp=1
|
||||
Icon=
|
||||
ExeOutput=
|
||||
ObjectOutput=
|
||||
OverrideOutput=0
|
||||
OverrideOutputName=CachedFactoryTest.exe
|
||||
HostApplication=
|
||||
Folders=
|
||||
CommandLine=
|
||||
UseCustomMakefile=0
|
||||
CustomMakefile=Makefile.loki
|
||||
IncludeVersionInfo=0
|
||||
SupportXPThemes=0
|
||||
CompilerSet=0
|
||||
CompilerSettings=0000000000000001000000
|
||||
|
||||
[VersionInfo]
|
||||
Major=0
|
||||
Minor=1
|
||||
Release=1
|
||||
Build=1
|
||||
LanguageID=1033
|
||||
CharsetID=1252
|
||||
CompanyName=
|
||||
FileVersion=
|
||||
FileDescription=Developed using the Dev-C++ IDE
|
||||
InternalName=
|
||||
LegalCopyright=
|
||||
LegalTrademarks=
|
||||
OriginalFilename=
|
||||
ProductName=
|
||||
ProductVersion=
|
||||
AutoIncBuildNr=0
|
||||
|
||||
|
||||
|
||||
|
||||
[Unit1]
|
||||
FileName=CachedFactoryTest.cpp
|
||||
CompileCpp=1
|
||||
Folder=CachedFactory
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
186
test/CachedFactory/CachedFactory.vcproj
Executable file
186
test/CachedFactory/CachedFactory.vcproj
Executable file
|
@ -0,0 +1,186 @@
|
|||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="8,00"
|
||||
Name="Factory"
|
||||
ProjectGUID="{925D5863-2F77-41B7-96F1-CC814762C40F}"
|
||||
RootNamespace="CachedFactory"
|
||||
Keyword="Win32Proj"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="Debug"
|
||||
IntermediateDirectory="Debug"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalOptions="-wd4996"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="..\..\include"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE _SECURE_SCL=1"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
Detect64BitPortabilityProblems="false"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
GenerateDebugInformation="true"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="Release"
|
||||
IntermediateDirectory="Release"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
AdditionalIncludeDirectories="..\..\include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||
RuntimeLibrary="2"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
Detect64BitPortabilityProblems="false"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
LinkIncremental="1"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<File
|
||||
RelativePath=".\CachedFactoryTest.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\include\loki\CachedFactory.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\include\loki\Key.h"
|
||||
>
|
||||
</File>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
414
test/CachedFactory/CachedFactoryTest.cpp
Executable file
414
test/CachedFactory/CachedFactoryTest.cpp
Executable file
|
@ -0,0 +1,414 @@
|
|||
#define USE_SEQUENCE
|
||||
|
||||
#include <iostream>
|
||||
#include <loki/Factory.h>
|
||||
|
||||
#ifdef LOKI_DISABLE_TYPELIST_MACROS
|
||||
#define USE_WQUENCE
|
||||
#endif
|
||||
|
||||
#ifdef USE_SEQUENCE
|
||||
#include <loki/Sequence.h>
|
||||
#endif
|
||||
|
||||
#include <loki/CachedFactory.h>
|
||||
#include <windows.h>
|
||||
|
||||
using std::cout;
|
||||
using std::cerr;
|
||||
using std::endl;
|
||||
using std::vector;
|
||||
using namespace Loki;
|
||||
|
||||
class AbstractProduct{
|
||||
public:
|
||||
virtual ~AbstractProduct(){};
|
||||
};
|
||||
|
||||
class Product : public AbstractProduct
|
||||
{
|
||||
public:
|
||||
Product(){}
|
||||
Product( int, int ){}
|
||||
};
|
||||
|
||||
class CostlyProduct : public AbstractProduct
|
||||
{
|
||||
public:
|
||||
CostlyProduct(){Sleep(100);}
|
||||
CostlyProduct( int, int ){Sleep(100);}
|
||||
};
|
||||
|
||||
class DebugProduct : public AbstractProduct
|
||||
{
|
||||
public:
|
||||
DebugProduct()
|
||||
{ cout << "Product Ctor()" << endl; }
|
||||
DebugProduct( int, int )
|
||||
{ cout << "Product Ctor(int, int)" << endl; }
|
||||
~DebugProduct()
|
||||
{ cout << "Product Dtor()" << endl; }
|
||||
};
|
||||
|
||||
CostlyProduct* createCostlyProductNull()
|
||||
{
|
||||
return new CostlyProduct;
|
||||
}
|
||||
|
||||
DebugProduct* createDebugProductNull()
|
||||
{
|
||||
return new DebugProduct;
|
||||
}
|
||||
|
||||
Product* createProductNull()
|
||||
{
|
||||
return new Product;
|
||||
}
|
||||
|
||||
Product* createProductInt(int a, int b)
|
||||
{
|
||||
return new Product(a,b);
|
||||
}
|
||||
|
||||
const int nullID(0);
|
||||
const int intID(1);
|
||||
|
||||
bool dispResult(const char* message, bool result)
|
||||
{
|
||||
cout << "## " << message << (result?" ...OK":" ...Failed !") << endl;
|
||||
return result;
|
||||
}
|
||||
|
||||
template<class CCache>
|
||||
bool unitTestCacheOverhead(int loop){
|
||||
std::clock_t start, elapsedNoCache, elapsedCache;
|
||||
start = std::clock();
|
||||
for(int i=0;i<loop;i++)
|
||||
delete createProductNull();
|
||||
elapsedNoCache = std::clock() - start;
|
||||
cout << " " << elapsedNoCache << " ms" ;
|
||||
CCache CC;
|
||||
CC.Register(nullID, createProductNull);
|
||||
start = std::clock();
|
||||
for(int i=0;i<loop;i++){
|
||||
AbstractProduct *pProduct(CC.CreateObject(nullID));
|
||||
CC.ReleaseObject(pProduct);
|
||||
}
|
||||
elapsedCache = std::clock() - start;
|
||||
cout << " " << elapsedCache << " ms";
|
||||
cout << " | average overhead per fetch : " <<(((double)(elapsedCache-elapsedNoCache)) / CLOCKS_PER_SEC * 1000 / loop) << " ms" << endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
void testCacheOverhead(){
|
||||
const int loop(1000000);
|
||||
cout << "Starting cache overhead test with " << loop << " loops" << endl;
|
||||
typedef CachedFactory< AbstractProduct, int, NullType, SimplePointer, AmountLimitedCreation, EvictRandom > CRandomEvict;
|
||||
typedef CachedFactory< AbstractProduct, int, NullType, SimplePointer, AmountLimitedCreation, EvictLRU > CLRUEvict;
|
||||
typedef CachedFactory< AbstractProduct, int, NullType, SimplePointer, AmountLimitedCreation, EvictAging > CAgingEvict;
|
||||
bool test1 = dispResult("Random policy", unitTestCacheOverhead< CRandomEvict >(loop));
|
||||
bool test2 = dispResult("LRU policy", unitTestCacheOverhead< CLRUEvict >(loop));
|
||||
bool test3 = dispResult("Aging policy", unitTestCacheOverhead< CAgingEvict >(loop));
|
||||
}
|
||||
void unitTestCachePerformance(int loop){
|
||||
typedef CachedFactory< AbstractProduct, int > CCache;
|
||||
std::clock_t start, elapsedNoCache, elapsedCache;
|
||||
start = std::clock();
|
||||
for(int i=0;i<loop;i++)
|
||||
delete createCostlyProductNull();
|
||||
elapsedNoCache = std::clock() - start;
|
||||
CCache CC;
|
||||
CC.Register(nullID, createCostlyProductNull);
|
||||
start = std::clock();
|
||||
for(int i=0;i<loop;i++){
|
||||
AbstractProduct *pProduct(CC.CreateObject(nullID));
|
||||
CC.ReleaseObject(pProduct);
|
||||
}
|
||||
elapsedCache = std::clock() - start;
|
||||
cout << "No cache "<<elapsedNoCache<<" ms | Cache "<<elapsedCache<<" ms | Efficiency " << (double(elapsedNoCache)/elapsedCache)-1 << endl;
|
||||
}
|
||||
|
||||
void testCachePerformance()
|
||||
{
|
||||
for(int i=1;i<=5;i++){
|
||||
cout << " || => " << i << " iterations" << endl;
|
||||
unitTestCachePerformance(i);
|
||||
}
|
||||
}
|
||||
|
||||
template< class Cache >
|
||||
std::clock_t typicalUse( Cache &CC, unsigned objectKind, unsigned maxObjectCount, unsigned maxIteration)
|
||||
{
|
||||
assert(objectKind>0);
|
||||
assert(maxIteration>0);
|
||||
assert(maxObjectCount>0);
|
||||
vector< AbstractProduct* > fetched;
|
||||
fetched.reserve(maxObjectCount);
|
||||
srand(0); // initialise the pseudo random operator
|
||||
std::clock_t start, end;
|
||||
try{
|
||||
// Registering objects
|
||||
for(int i=0;i<objectKind;i++)
|
||||
CC.Register(i, createProductNull);
|
||||
// Simulating real use
|
||||
start = std::clock();
|
||||
for(unsigned i=0;i<maxIteration;i++)
|
||||
{
|
||||
const size_t size(fetched.size());
|
||||
if( size == maxObjectCount ){
|
||||
CC.ReleaseObject(fetched.back());
|
||||
fetched.pop_back();
|
||||
} else if(size == 0){
|
||||
fetched.push_back(CC.CreateObject(int(objectKind*rand()/(RAND_MAX + 1.0))));
|
||||
} else if(rand()<RAND_MAX/2){
|
||||
CC.ReleaseObject(fetched.back());
|
||||
fetched.pop_back();
|
||||
} else {
|
||||
fetched.push_back(CC.CreateObject(int(objectKind*rand()/(RAND_MAX + 1.0))));
|
||||
}
|
||||
}
|
||||
end = std::clock();
|
||||
}catch(std::exception &e)
|
||||
{
|
||||
cout << "Error in executing typicalUse " << endl << e.what() << endl;
|
||||
}
|
||||
// Cleaning in use objects
|
||||
for(std::vector<AbstractProduct*>::iterator itr = fetched.begin(); itr!=fetched.end(); itr++)
|
||||
CC.ReleaseObject(*itr);
|
||||
fetched.clear();
|
||||
return end-start;
|
||||
}
|
||||
|
||||
template< class Cache >
|
||||
void displayTypicalUse(Cache &CC, unsigned objectKind, unsigned maxObjectCount, unsigned maxIteration)
|
||||
{
|
||||
CC.displayCacheType();
|
||||
cout << "====> " << typicalUse<Cache>(CC, objectKind, maxObjectCount, maxIteration) << " ms" << endl;
|
||||
}
|
||||
|
||||
void testTypicalUse()
|
||||
{
|
||||
const unsigned objectKind(10);
|
||||
const unsigned maxObjectCount(300);
|
||||
const unsigned maxIteration(1000000);
|
||||
cout << "# " << objectKind << " objects registered in the Factory" << endl;
|
||||
cout << "# Cache contains max " << maxObjectCount << " objects" << endl;
|
||||
cout << "# Test performs "<< maxIteration <<" iterations" << endl;
|
||||
{
|
||||
typedef CachedFactory< AbstractProduct, int, NullType, SimplePointer, AlwaysCreate, EvictRandom, SimpleStatisticPolicy > CRandomEvict;
|
||||
CRandomEvict cache;
|
||||
displayTypicalUse<CRandomEvict>( cache, objectKind, maxObjectCount, maxIteration);
|
||||
}
|
||||
{
|
||||
typedef CachedFactory< AbstractProduct, int, NullType, SimplePointer, AlwaysCreate, EvictLRU, SimpleStatisticPolicy > CLRUEvict;
|
||||
CLRUEvict cache;
|
||||
displayTypicalUse( cache, objectKind, maxObjectCount, maxIteration);
|
||||
}
|
||||
{
|
||||
typedef CachedFactory< AbstractProduct, int, NullType, SimplePointer, AlwaysCreate, EvictAging, SimpleStatisticPolicy > CAgingEvict;
|
||||
CAgingEvict cache;
|
||||
displayTypicalUse( cache, objectKind, maxObjectCount, maxIteration);
|
||||
}
|
||||
}
|
||||
|
||||
template< class Cache >
|
||||
bool testEvictionError()
|
||||
{
|
||||
bool testPassed = false;
|
||||
Cache CC;
|
||||
CC.Register(nullID, createProductNull);
|
||||
CC.setMaxCreation(1);
|
||||
AbstractProduct *pProduct1 = NULL, *pProduct2 = NULL;
|
||||
try{
|
||||
pProduct1 = CC.CreateObject(nullID); // should be OK
|
||||
pProduct2 = CC.CreateObject(nullID); // should cast an exception
|
||||
} catch(std::exception &e){
|
||||
if(strcmp(e.what(), EvictionException().what())==0)
|
||||
testPassed = true;
|
||||
}
|
||||
if(pProduct1!=NULL)
|
||||
CC.ReleaseObject(pProduct1);
|
||||
if(pProduct2!=NULL)
|
||||
CC.ReleaseObject(pProduct2);
|
||||
return testPassed;
|
||||
}
|
||||
|
||||
bool testAllEvictionError()
|
||||
{
|
||||
typedef CachedFactory< AbstractProduct, int, NullType, SimplePointer, AmountLimitedCreation, EvictRandom > CRandomEvict;
|
||||
typedef CachedFactory< AbstractProduct, int, NullType, SimplePointer, AmountLimitedCreation, EvictLRU > CLRUEvict;
|
||||
typedef CachedFactory< AbstractProduct, int, NullType, SimplePointer, AmountLimitedCreation, EvictAging > CAgingEvict;
|
||||
bool test1 = dispResult("Random policy", testEvictionError< CRandomEvict >());
|
||||
bool test2 = dispResult("LRU policy", testEvictionError< CLRUEvict >());
|
||||
bool test3 = dispResult("Aging policy", testEvictionError< CAgingEvict >());
|
||||
return test1 && test2 && test3;
|
||||
}
|
||||
|
||||
bool testAmountLimitedCreation()
|
||||
{
|
||||
typedef CachedFactory< AbstractProduct, int, NullType, SimplePointer, AmountLimitedCreation, EvictRandom, SimpleStatisticPolicy > CCache;
|
||||
CCache CC;
|
||||
CC.Register(nullID, createDebugProductNull);
|
||||
CC.Register(intID, createDebugProductNull);
|
||||
// CC.setMaxCreation(0); <== would break on assert, such a cache is useless
|
||||
CC.setMaxCreation(1);
|
||||
AbstractProduct *pProduct1 = NULL, *pProduct2 = NULL;
|
||||
pProduct1 = CC.CreateObject(nullID); // should be OK
|
||||
CC.ReleaseObject(pProduct1);
|
||||
pProduct2 = CC.CreateObject(intID); // should call the evict method
|
||||
if(pProduct1!=NULL)
|
||||
CC.ReleaseObject(pProduct1);
|
||||
if(pProduct2!=NULL)
|
||||
CC.ReleaseObject(pProduct2);
|
||||
return (CC.getDestroyed()==1);
|
||||
}
|
||||
|
||||
bool testRateLimitedFetchPolicy(bool waitBetweenFetch)
|
||||
{
|
||||
typedef CachedFactory< AbstractProduct, int, NullType, SimplePointer, RateLimitedCreation > CCache;
|
||||
CCache CC;
|
||||
CC.Register(nullID, createProductNull);
|
||||
CC.setRate(2/*max two fetchs*/,100/*within 100 ms*/);
|
||||
|
||||
bool exceptionOccured = false;
|
||||
const int number(5);
|
||||
const int sleepTime(60);
|
||||
AbstractProduct *products[number];
|
||||
for(int i=0;i<number;i++) products[i]=NULL; // initializing
|
||||
try{
|
||||
for(int i=0;i<number;i++){
|
||||
products[i] = CC.CreateObject(nullID);
|
||||
if(waitBetweenFetch && (i!=(number-1))){
|
||||
Sleep(sleepTime);
|
||||
}
|
||||
}
|
||||
} catch (std::exception &e){
|
||||
exceptionOccured = true;
|
||||
cout << "Exception occured" << endl << e.what() <<endl;
|
||||
}
|
||||
|
||||
// Cleaning things by releasing
|
||||
for(int i=0;i<number;i++)
|
||||
if(products[i]!=NULL)
|
||||
CC.ReleaseObject(products[i]);
|
||||
|
||||
return exceptionOccured;
|
||||
}
|
||||
|
||||
bool fullTestRateLimitedFetchPolicy()
|
||||
{
|
||||
cout << " || => Setting rate limit to 2 fetch within 100 ms." << endl;
|
||||
cout << " || => generating 5 objects " << endl;
|
||||
bool test1 = dispResult("Fast creation", testRateLimitedFetchPolicy(false)==true);
|
||||
cout << " || => generating 5 objects with 60ms between each Fetch" << endl;
|
||||
bool test2 = dispResult("Slow creation", testRateLimitedFetchPolicy(true)==false);
|
||||
return test1 && test2;
|
||||
}
|
||||
|
||||
bool testRelease(){
|
||||
typedef CachedFactory< AbstractProduct, int > CCache;
|
||||
CCache CC;
|
||||
CC.Register(nullID, createProductNull);
|
||||
AbstractProduct *pProduct = NULL;
|
||||
CC.ReleaseObject(pProduct);
|
||||
cout << "Caching failed" << endl;
|
||||
}
|
||||
|
||||
|
||||
bool testCache()
|
||||
{
|
||||
typedef CachedFactory< AbstractProduct, int, Seq< int, int > > CCache2Parm;
|
||||
|
||||
CCache2Parm CC2;
|
||||
CC2.Register(intID, createProductInt);
|
||||
AbstractProduct * pProduct = CC2.CreateObject(intID,5,3);
|
||||
AbstractProduct * pSave(pProduct);
|
||||
CC2.ReleaseObject(pProduct);
|
||||
pProduct = CC2.CreateObject(intID,5,3);
|
||||
if(pSave != pProduct)
|
||||
{
|
||||
cout << "Caching failed" << endl;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
CC2.ReleaseObject(pProduct);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void dispText(char* text)
|
||||
{
|
||||
cout << endl;
|
||||
cout << "##========================================"<< endl;
|
||||
cout << "## " << text << endl;
|
||||
cout << "##========================================"<< endl;
|
||||
}
|
||||
|
||||
void dispText(char* text, char* comment)
|
||||
{
|
||||
cout << endl;
|
||||
cout << "##========================================"<< endl;
|
||||
cout << "## " << text << endl;
|
||||
cout << "## " << comment << endl;
|
||||
cout << "##========================================"<< endl;
|
||||
}
|
||||
|
||||
void separator()
|
||||
{
|
||||
cout << endl << endl;
|
||||
}
|
||||
|
||||
void performanceTests()
|
||||
{
|
||||
dispText(" ==> Performance tests <==");
|
||||
separator();
|
||||
dispText("Test typical use", "tries different Cache strategies in a typical use configuration");
|
||||
testTypicalUse();
|
||||
separator();
|
||||
dispText("Test efficiency","Comparison between generating costly objects (100ms) and using Cache");
|
||||
testCachePerformance();
|
||||
separator();
|
||||
dispText("Test overhead","Intensive use of Cache to determine the cache time overhead");
|
||||
testCacheOverhead();
|
||||
separator();
|
||||
}
|
||||
|
||||
void reliabilityTests()
|
||||
{
|
||||
dispText(" ==> Reliability tests <==");
|
||||
separator();
|
||||
dispText("Test caching", "Trying to Create, Release, Create and see if Cache gives the same object");
|
||||
bool cacheResult= dispResult("caching result", testCache());
|
||||
separator();
|
||||
dispText("Test RateLimitedFetch policy",
|
||||
"Trying to quickly create objects, then same scenario with pause in between");
|
||||
bool rateLimitedResult= dispResult("RateLimitedFetch policy result",fullTestRateLimitedFetchPolicy());
|
||||
separator();
|
||||
dispText("Test AmountLimitedCreation policy","Trying to create 2 objects with a limit of 1 creation max, you should see a destroyed object (eviction)");
|
||||
bool amountLimitedResult = dispResult("AmountLimitedCreation policy result", testAmountLimitedCreation());
|
||||
separator();
|
||||
dispText("Test eviction error", "An eviction should occur (Creation Policy), but all object are in use");
|
||||
bool evictionTest = dispResult("eviction error test result", testAllEvictionError());
|
||||
separator();
|
||||
if(cacheResult&&rateLimitedResult&&amountLimitedResult&&evictionTest)
|
||||
dispText("All tests passed successfully");
|
||||
else
|
||||
dispText("One or more test have failed");
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
try{
|
||||
performanceTests();
|
||||
reliabilityTests();
|
||||
}catch(std::exception &e){
|
||||
cerr << e.what() << endl;
|
||||
cerr << "Error while performing tests" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO provide :
|
||||
// +Efficiency tests
|
||||
// +Overhead tests
|
||||
// +Fiability tests
|
16
test/CachedFactory/Makefile
Executable file
16
test/CachedFactory/Makefile
Executable file
|
@ -0,0 +1,16 @@
|
|||
include ../Makefile.common
|
||||
|
||||
BIN := Factory$(BIN_SUFFIX)
|
||||
SRC := Factory.cpp
|
||||
OBJ := $(SRC:.cpp=.o)
|
||||
|
||||
.PHONY: all clean
|
||||
all: $(BIN)
|
||||
clean: cleandeps
|
||||
$(RM) $(BIN)
|
||||
$(RM) $(OBJ)
|
||||
|
||||
$(BIN): $(OBJ)
|
||||
$(CXX) $(LDFLAGS) -o $@ $^ $(LDLIBS)
|
||||
|
||||
include ../../Makefile.deps
|
7
test/CachedFactory/make.msvc.bat
Executable file
7
test/CachedFactory/make.msvc.bat
Executable file
|
@ -0,0 +1,7 @@
|
|||
|
||||
cl -c -Zm200 -O2 -DNDEBUG -MT -EHsc -GR -W4 -wd4710 -I"." -I"..\..\include" CachedFactoryTest.cpp.cpp
|
||||
|
||||
link /NOLOGO /SUBSYSTEM:CONSOLE /incremental:no /OUT:"main-msvc.exe" ..\..\lib\loki.lib CachedFactoryTest.cpp.obj
|
||||
|
||||
del *.obj
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue