opm-common
Loading...
Searching...
No Matches
MessageLimiter.hpp
1/*
2 Copyright 2016 SINTEF ICT, Applied Mathematics.
3
4 This file is part of the Open Porous Media project (OPM).
5
6 OPM is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 OPM is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with OPM. If not, see <http://www.gnu.org/licenses/>.
18*/
19
20#ifndef OPM_MESSAGELIMITER_HEADER_INCLUDED
21#define OPM_MESSAGELIMITER_HEADER_INCLUDED
22
23#include <cstdint>
24#include <map>
25#include <string>
26#include <unordered_map>
27
28namespace Opm
29{
30
31
34 {
35 public:
37 enum { NoLimit = -1 };
38
57
59 MessageLimiter() = default;
60
67 explicit MessageLimiter(const int tag_limit)
68 : MessageLimiter { tag_limit, {} }
69 {}
70
71 MessageLimiter(const int tag_limit, const std::map<std::int64_t, int>& category_limits)
72 : tag_limit_ { (tag_limit < 0) ? NoLimit : tag_limit }
73 , category_limits_ { category_limits }
74 {}
75
77 int tagMessageLimit() const
78 {
79 return tag_limit_;
80 }
81
89 Response handleMessageLimits(const std::string& tag,
90 const std::int64_t messageMask) const
91 {
93
94 // Deal with tag limits.
95 if (!tag.empty() && (this->tag_limit_ != NoLimit)) {
96 res = this->countBasedResponseTag(this->increaseTagCount(tag));
97 }
98
99 if (res != Response::PrintMessage) {
100 // Tag count reached limit. Do not include message in
101 // category count.
102 return res;
103 }
104
105 // Tag count within limits. Include message in category count.
106 const auto count = this->increaseCategoryCount(messageMask);
107
108 if (const auto limitPos = this->category_limits_.find(messageMask);
109 (limitPos != this->category_limits_.end()) &&
110 (limitPos->second != NoLimit))
111 {
112 // There is a defined category limit for 'messageMask'.
113 // Generate response based on this limit.
114 res = this->countBasedResponseCategory(count, limitPos->second);
115 }
116
117 // PrintMessage or category based response.
118 return res;
119 }
120
128 int categoryMessageCount(const std::int64_t category) const
129 {
130 const auto countPos = this->category_counts_.find(category);
131
132 return (countPos != this->category_counts_.end())
133 ? countPos->second : 0;
134 }
135
136 private:
140 int tag_limit_ {NoLimit};
141
147 std::map<std::int64_t, int> category_limits_{};
148
150 mutable std::unordered_map<std::string, int> tag_counts_{};
151
153 mutable std::map<std::int64_t, int> category_counts_{};
154
155 int increaseTagCount(const std::string& tag) const
156 {
157 return increaseCount(tag, this->tag_counts_);
158 }
159
160 int increaseCategoryCount(const std::int64_t messageMask) const
161 {
162 return increaseCount(messageMask, this->category_counts_);
163 }
164
165 Response countBasedResponseTag(const int count) const
166 {
167 return response(count, this->tag_limit_,
168 Response::JustOverTagLimit,
169 Response::OverTagLimit);
170 }
171
172 Response countBasedResponseCategory(const int count,
173 const int category_limit) const
174 {
175 return response(count, category_limit,
176 Response::JustOverCategoryLimit,
177 Response::OverCategoryLimit);
178 }
179
180 template <typename Key, class CountMap>
181 static int increaseCount(const Key& key, CountMap& counts)
182 {
183 return ++counts.try_emplace(key, 0).first->second;
184 }
185
186 static Response response(const int count,
187 const int limit,
188 const Response justOverLimit,
189 const Response overLimit)
190 {
191 if (count <= limit) {
192 return Response::PrintMessage;
193 } else if (count == limit + 1) {
194 return justOverLimit;
195 } else {
196 return overLimit;
197 }
198 }
199 };
200
201} // namespace Opm
202
203#endif // OPM_MESSAGELIMITER_HEADER_INCLUDED
Handles limiting the number of messages with the same tag.
Definition MessageLimiter.hpp:34
Response
Used for handleMessageLimits() return type (see that function).
Definition MessageLimiter.hpp:41
@ JustOverCategoryLimit
Message has reached the current limit for this category.
Definition MessageLimiter.hpp:49
@ JustOverTagLimit
Message has reached the current limit for this tag.
Definition MessageLimiter.hpp:46
@ OverTagLimit
Message is over the current limit for this tag.
Definition MessageLimiter.hpp:52
@ OverCategoryLimit
Message is over the current limit of this category.
Definition MessageLimiter.hpp:55
@ PrintMessage
Message should be printed. Not affected by any limit.
Definition MessageLimiter.hpp:43
MessageLimiter(const int tag_limit)
Construct with given limit to number of messages with the same tag.
Definition MessageLimiter.hpp:67
int tagMessageLimit() const
The tag message limit (same for all tags).
Definition MessageLimiter.hpp:77
int categoryMessageCount(const std::int64_t category) const
Retrieve message count for specific category.
Definition MessageLimiter.hpp:128
Response handleMessageLimits(const std::string &tag, const std::int64_t messageMask) const
If (tag count == tag limit + 1) for the passed tag, respond JustOverTagLimit.
Definition MessageLimiter.hpp:89
MessageLimiter()=default
Default constructor, no limit to the number of messages.
This class implements a small container which holds the transmissibility mulitpliers for all the face...
Definition Exceptions.hpp:30