]> git.ipfire.org Git - thirdparty/squid.git/blob - src/adaptation/ServiceGroups.h
Merged from trunk
[thirdparty/squid.git] / src / adaptation / ServiceGroups.h
1 #ifndef SQUID_ADAPTATION__SERVICE_GROUPS_H
2 #define SQUID_ADAPTATION__SERVICE_GROUPS_H
3
4 #include "SquidString.h"
5 #include "Array.h"
6 #include "RefCount.h"
7 #include "adaptation/Elements.h"
8 #include "adaptation/forward.h"
9
10 namespace Adaptation
11 {
12
13 // Interface for grouping adaptation services together.
14 // Specific groups differ in how the first and the next services are selected
15 class ServiceGroup: public RefCountable
16 {
17 public:
18 typedef RefCount<ServiceGroup> Pointer;
19
20 typedef Vector<String> Store;
21 typedef String Id;
22 typedef unsigned int Pos; // Vector<>::poistion_type
23 friend class ServicePlan;
24
25 public:
26 ServiceGroup(const String &aKind, bool areAllServicesSame);
27 virtual ~ServiceGroup();
28
29 virtual void parse();
30 virtual void finalize(); // called after all are parsed
31
32 bool wants(const ServiceFilter &filter) const;
33
34 protected:
35 ///< whether this group has a service at the specified pos
36 bool has(const Pos pos) const {
37 // does not check that the service at pos still exists
38 return pos < services.size(); // unsigned pos is never negative
39 }
40
41 /// these methods control group iteration; used by ServicePlan
42
43 /// find next to try after failure, starting with pos
44 bool findReplacement(const ServiceFilter &filter, Pos &pos) const;
45 /// find next to link after success, starting with pos
46 bool findLink(const ServiceFilter &filter, Pos &pos) const;
47
48 private:
49 ServicePointer at(const Pos pos) const;
50 bool findService(const ServiceFilter &filter, Pos &pos) const;
51
52 void checkUniqueness(const Pos checkedPos) const;
53 void finalizeMsg(const char *msg, const String &culprit, bool error) const;
54
55 public:
56 String kind;
57 Id id;
58 Store services;
59
60 Method method; /// based on the first added service
61 VectPoint point; /// based on the first added service
62
63 const bool allServicesSame; // whether we can freely substitute services
64 };
65
66 // a group of equivalent services; one service per set is usually used
67 class ServiceSet: public ServiceGroup
68 {
69 public:
70 ServiceSet();
71
72 protected:
73 virtual bool replace(Pos &pos) const { return has(++pos); }
74 virtual bool advance(Pos &pos) const { return false; }
75 };
76
77 // corner case: a group consisting of one service
78 class SingleService: public ServiceGroup
79 {
80 public:
81 SingleService(const String &aServiceKey);
82
83 protected:
84 virtual bool replace(Pos &pos) const { return false; }
85 virtual bool advance(Pos &pos) const { return false; }
86 };
87
88 /// a group of services that must be used one after another
89 class ServiceChain: public ServiceGroup
90 {
91 public:
92 ServiceChain();
93
94 protected:
95 virtual bool replace(Pos &pos) const { return false; }
96 virtual bool advance(Pos &pos) const { return has(++pos); }
97 };
98
99 /// a temporary service chain built upon another service request
100 class DynamicServiceChain: public ServiceChain
101 {
102 public:
103 DynamicServiceChain(const String &srvcs, const ServiceGroupPointer prev);
104 };
105
106
107 /** iterates services stored in a group; iteration is not linear because we
108 need to both replace failed services and advance to the next chain link */
109 class ServicePlan {
110 public:
111 typedef unsigned int Pos; // Vector<>::poistion_type
112
113 public:
114 ServicePlan();
115 explicit ServicePlan(const ServiceGroupPointer &g, const ServiceFilter &filter);
116
117 ///< true iff there are no more services planned
118 bool exhausted() const { return atEof; }
119
120 /// returns nil if the plan is complete
121 ServicePointer current() const; ///< current service
122 ServicePointer replacement(const ServiceFilter &filter); ///< next to try after failure
123 ServicePointer next(const ServiceFilter &filter); ///< next in chain after success
124
125 std::ostream &print(std::ostream &os) const;
126
127 private:
128 ServiceGroupPointer group; ///< the group we are iterating
129 Pos pos; ///< current service position within the group
130 bool atEof; ///< cached information for better performance
131 };
132
133 inline
134 std::ostream &operator <<(std::ostream &os, const ServicePlan &p)
135 {
136 return p.print(os);
137 }
138
139 typedef Vector<ServiceGroupPointer> Groups;
140 extern Groups &AllGroups();
141 extern ServiceGroupPointer FindGroup(const ServiceGroup::Id &id);
142
143
144 } // namespace Adaptation
145
146 #endif /* SQUID_ADAPTATION__SERVICE_GROUPS_H */
147