102 lines
4.1 KiB
C++
102 lines
4.1 KiB
C++
/****************************************************************/
|
|
/* NAME: */
|
|
/* ACCT: kostadis */
|
|
/* FILE: BPSPolicy.H */
|
|
/* ASGN: */
|
|
/* DATE: Sat Jul 8 15:43:18 1995 */
|
|
/****************************************************************/
|
|
|
|
|
|
#ifndef BPSPOLICY_HEADER
|
|
#define BPSPOLICY_HEADER
|
|
#include <bps.h>
|
|
class BPSSSPartition;
|
|
class BPSJob;
|
|
class BPSSSPartitionUnit;
|
|
|
|
#include <Thread.H>
|
|
|
|
|
|
|
|
/*****************************************************************
|
|
CLASS NAME : BPSPolicy
|
|
|
|
The policy in the BPS is responsible for finding and creating a job
|
|
based on the request structure and the partition it can search
|
|
in. Since the optimal policy is 'NP complete' the type of policy
|
|
implemented can be globally sub optimal but locally optimal for
|
|
particular types of requests, partition types or desired goals. The
|
|
trick was to create a mechanism that was flexible and extensible at
|
|
the same time. The central idea was that adding a new policy had to
|
|
not require modifying ANY existing source (so that a customer could
|
|
use it). The most common approach is to use dynamic linking. The
|
|
approach used here is an idiom referred to by Coplien in _Advanced
|
|
C++ Idioms_ as 'exemplars'. The idea, derived from Self and
|
|
Smalltalk, is that a type is also an object. If a type is an object,
|
|
and you can modify an object you can also modify a type. So the
|
|
idiom Coplien describes is to at run time create a list of types and
|
|
then later on, from that list create the object you want, by passing
|
|
some sort of information to a 'clone' method that scans the list
|
|
looking for a match. To set the list up, Coplien uses static
|
|
instantiations of variables. Each type derives from some common base
|
|
class. The base class has a static list_ and a non static next_
|
|
member variable. Each 'type' that wants to register itself to the
|
|
system creates a static instance of itself, using the base
|
|
constructor that sets the list_ variable to this and the next_
|
|
variable to list_. At run time, each static instance adds itself to
|
|
the list. The only important consideration is where the head of the
|
|
list is because the order of static initialization is undefined
|
|
(stroustrop 'Design and Evolution of C++' discusses why). Whereas
|
|
for Coplien that was not an issue because all the statics were
|
|
initialized in the same source file, this is not the case with this
|
|
system. To keep track of the 'head of the list' we assign to
|
|
BPSPolicyManager::base_, the this pointer of the policy object being
|
|
initialized. This way the BPSPolicyManager which actually performs
|
|
the scan always has a pointer to the head of the list. The head of
|
|
the list, btw, is NULL terminated. The net effect is that adding a
|
|
new policy, merely requires, compiling the new policy object and
|
|
relinking the system.
|
|
|
|
|
|
|
|
****************************************************************/
|
|
|
|
|
|
class BPSPolicy {
|
|
BPSPolicy();
|
|
BPSPolicy& operator=(BPSPolicy&);
|
|
BPSPolicy(BPSPolicy&);
|
|
static BPSPolicy* list_;
|
|
BPSPolicy* next_;
|
|
friend class BPSPolicyManager;
|
|
protected:
|
|
bps_policy_id_t id_; // the type id
|
|
bps_request_t* request_;
|
|
BPSSSPartition* partition_;
|
|
virtual bps_time_t searchStart(const bps_time_t&) = 0;
|
|
virtual error_t isMatch(BPSSSPartitionUnit* unit) = 0;
|
|
public:
|
|
BPSPolicy(char* policy_id); // used to create policy types
|
|
// used to create policy objects
|
|
BPSPolicy(bps_request_t* request,BPSSSPartition* partition);
|
|
~BPSPolicy();
|
|
|
|
// returns an object of the same type
|
|
virtual error_t clone(const bps_request_t* request, BPSSSPartition* partition,
|
|
BPSPolicy*& policy) = 0;
|
|
|
|
|
|
// returns the job found by search
|
|
virtual error_t getJob(BPSJob*& job, const bps_magic_cookie_t& cookie) = 0;
|
|
|
|
// searches for a job in the given partition
|
|
virtual error_t search() = 0;
|
|
int operator==(const bps_policy_id_t& id){
|
|
return bps_policy_equal(&id_,(bps_policy_id_t*)&id);
|
|
}
|
|
};
|
|
|
|
BPSPolicy* BPSPolicy::list_ = 0;
|
|
|
|
#endif
|