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