My Project
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 <opm/common/OpmLog/LogUtil.hpp>
24#include <cassert>
25#include <map>
26#include <string>
27#include <unordered_map>
28#include <vector>
29
30
31namespace Opm
32{
33
34
37 {
38 public:
40 enum { NoLimit = -1 };
41
44 : MessageLimiter(NoLimit)
45 {
46 }
47
54 explicit MessageLimiter(const int tag_limit)
55 : tag_limit_(tag_limit < 0 ? NoLimit : tag_limit),
56 category_limits_({{Log::MessageType::Debug, NoLimit},
57 {Log::MessageType::Note, NoLimit},
58 {Log::MessageType::Info, NoLimit},
59 {Log::MessageType::Warning, NoLimit},
60 {Log::MessageType::Error, NoLimit},
61 {Log::MessageType::Problem, NoLimit},
62 {Log::MessageType::Bug, NoLimit}})
63 {
64 }
65
66 MessageLimiter(const int tag_limit, const std::map<int64_t, int>& category_limits)
67 : tag_limit_(tag_limit < 0 ? NoLimit : tag_limit),
68 category_limits_(category_limits)
69 {
70 // Must ensure NoLimit for categories that are not
71 // explicitly specified in the input.
72 for (auto category : { Log::MessageType::Debug,
73 Log::MessageType::Note,
74 Log::MessageType::Info,
75 Log::MessageType::Warning,
76 Log::MessageType::Error,
77 Log::MessageType::Problem,
78 Log::MessageType::Bug }) {
79 category_limits_.try_emplace(category, NoLimit);
80 }
81 }
82
84 int tagMessageLimit() const
85 {
86 return tag_limit_;
87 }
88
90 const std::map<int64_t, int>& categoryMessageLimits() const
91 {
92 return category_limits_;
93 }
94
96 const std::map<int64_t, int>& categoryMessageCounts() const
97 {
98 return category_counts_;
99 }
100
103 enum class Response
104 {
105 PrintMessage, JustOverTagLimit, JustOverCategoryLimit, OverTagLimit, OverCategoryLimit
106 };
107
115 Response handleMessageLimits(const std::string& tag, const int64_t messageMask)
116 {
117 Response res = Response::PrintMessage;
118
119 // Deal with tag limits.
120 if (!tag.empty() && tag_limit_ != NoLimit) {
121 // See if tag already encountered.
122 auto it = tag_counts_.find(tag);
123 if (it != tag_counts_.end()) {
124 // Already encountered this tag. Increment its count.
125 const int count = ++it->second;
126 res = countBasedResponseTag(count);
127 } else {
128 // First encounter of this tag. Insert 1.
129 tag_counts_.insert({tag, 1});
130 res = countBasedResponseTag(1);
131 }
132 }
133
134 // If tag count reached the limit, the message is not counted
135 // towards the category limits.
136 if (res == Response::PrintMessage) {
137 // We are *not* above the tag limit, consider category limit.
138 const int count = ++category_counts_[messageMask];
139 if (category_limits_[messageMask] != NoLimit) {
140 res = countBasedResponseCategory(count, messageMask);
141 }
142 }
143
144 return res;
145 }
146
147 private:
148 Response countBasedResponseTag(const int count) const
149 {
150 if (count <= tag_limit_) {
151 return Response::PrintMessage;
152 } else if (count == tag_limit_ + 1) {
153 return Response::JustOverTagLimit;
154 } else {
155 return Response::OverTagLimit;
156 }
157 }
158
159
160 Response countBasedResponseCategory(const int count, const int64_t messageMask) const
161 {
162 const int limit = category_limits_.at(messageMask);
163 if (count <= limit) {
164 return Response::PrintMessage;
165 } else if (count == limit + 1) {
166 return Response::JustOverCategoryLimit;
167 } else {
168 return Response::OverCategoryLimit;
169 }
170 }
171
172 int tag_limit_;
173 std::unordered_map<std::string, int> tag_counts_;
174 std::map<int64_t, int> category_limits_;
175 std::map<int64_t, int> category_counts_ = {{Log::MessageType::Note, 0},
176 {Log::MessageType::Info, 0},
177 {Log::MessageType::Warning, 0},
178 {Log::MessageType::Error, 0},
179 {Log::MessageType::Problem, 0},
180 {Log::MessageType::Bug, 0}};
181 };
182
183
184
185} // namespace Opm
186
187#endif // OPM_MESSAGELIMITER_HEADER_INCLUDED
Handles limiting the number of messages with the same tag.
Definition MessageLimiter.hpp:37
Response handleMessageLimits(const std::string &tag, const int64_t messageMask)
If (tag count == tag limit + 1) for the passed tag, respond JustOverTagLimit.
Definition MessageLimiter.hpp:115
const std::map< int64_t, int > & categoryMessageCounts() const
The category message counts.
Definition MessageLimiter.hpp:96
Response
Used for handleMessageLimits() return type (see that function).
Definition MessageLimiter.hpp:104
MessageLimiter(const int tag_limit)
Construct with given limit to number of messages with the same tag.
Definition MessageLimiter.hpp:54
const std::map< int64_t, int > & categoryMessageLimits() const
The category message limits.
Definition MessageLimiter.hpp:90
int tagMessageLimit() const
The tag message limit (same for all tags).
Definition MessageLimiter.hpp:84
MessageLimiter()
Default constructor, no limit to the number of messages.
Definition MessageLimiter.hpp:43
This class implements a small container which holds the transmissibility mulitpliers for all the face...
Definition Exceptions.hpp:30