]> git.ipfire.org Git - thirdparty/squid.git/blob - src/adaptation/ServiceGroups.h
SourceFormat Enforcement
[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 Store removedServices;///< the disabled services in the case ecap or icap is disabled
60
61 Method method; /// based on the first added service
62 VectPoint point; /// based on the first added service
63
64 const bool allServicesSame; // whether we can freely substitute services
65 };
66
67 // a group of equivalent services; one service per set is usually used
68 class ServiceSet: public ServiceGroup
69 {
70 public:
71 ServiceSet();
72
73 protected:
74 virtual bool replace(Pos &pos) const { return has(++pos); }
75 virtual bool advance(Pos &pos) const { return false; }
76 };
77
78 // corner case: a group consisting of one service
79 class SingleService: public ServiceGroup
80 {
81 public:
82 SingleService(const String &aServiceKey);
83
84 protected:
85 virtual bool replace(Pos &pos) const { return false; }
86 virtual bool advance(Pos &pos) const { return false; }
87 };
88
89 /// a group of services that must be used one after another
90 class ServiceChain: public ServiceGroup
91 {
92 public:
93 ServiceChain();
94
95 protected:
96 virtual bool replace(Pos &pos) const { return false; }
97 virtual bool advance(Pos &pos) const { return has(++pos); }
98 };
99
100 /// a temporary service chain built upon another service request
101 class DynamicServiceChain: public ServiceChain
102 {
103 public:
104 DynamicServiceChain(const DynamicGroupCfg &cfg, const ServiceFilter &f);
105
106 /// separates dynamic services matching current location from future ones
107 static void Split(const ServiceFilter &filter, const String &ids,
108 DynamicGroupCfg &current, DynamicGroupCfg &future);
109 };
110
111 /** iterates services stored in a group; iteration is not linear because we
112 need to both replace failed services and advance to the next chain link */
113 class ServicePlan
114 {
115 public:
116 typedef unsigned int Pos; // Vector<>::poistion_type
117
118 public:
119 ServicePlan();
120 explicit ServicePlan(const ServiceGroupPointer &g, const ServiceFilter &filter);
121
122 ///< true iff there are no more services planned
123 bool exhausted() const { return atEof; }
124
125 /// returns nil if the plan is complete
126 ServicePointer current() const; ///< current service
127 ServicePointer replacement(const ServiceFilter &filter); ///< next to try after failure
128 ServicePointer next(const ServiceFilter &filter); ///< next in chain after success
129
130 std::ostream &print(std::ostream &os) const;
131
132 private:
133 ServiceGroupPointer group; ///< the group we are iterating
134 Pos pos; ///< current service position within the group
135 bool atEof; ///< cached information for better performance
136 };
137
138 inline
139 std::ostream &operator <<(std::ostream &os, const ServicePlan &p)
140 {
141 return p.print(os);
142 }
143
144 typedef Vector<ServiceGroupPointer> Groups;
145 extern Groups &AllGroups();
146 extern ServiceGroupPointer FindGroup(const ServiceGroup::Id &id);
147
148 } // namespace Adaptation
149
150 #endif /* SQUID_ADAPTATION__SERVICE_GROUPS_H */
151