Loading...
Searching...
No Matches
MessageLimiter.hpp
/*
Copyright 2016 SINTEF ICT, Applied Mathematics.
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OPM_MESSAGELIMITER_HEADER_INCLUDED
#define OPM_MESSAGELIMITER_HEADER_INCLUDED
#include <cstdint>
#include <map>
#include <string>
#include <unordered_map>
namespace Opm
{
class MessageLimiter
{
public:
enum { NoLimit = -1 };
enum class Response
{
PrintMessage,
JustOverTagLimit,
JustOverCategoryLimit,
OverTagLimit,
OverCategoryLimit,
};
MessageLimiter() = default;
explicit MessageLimiter(const int tag_limit)
: MessageLimiter { tag_limit, {} }
{}
MessageLimiter(const int tag_limit, const std::map<std::int64_t, int>& category_limits)
: tag_limit_ { (tag_limit < 0) ? NoLimit : tag_limit }
, category_limits_ { category_limits }
{}
int tagMessageLimit() const
{
return tag_limit_;
}
Response handleMessageLimits(const std::string& tag,
const std::int64_t messageMask) const
{
Response res = Response::PrintMessage;
// Deal with tag limits.
if (!tag.empty() && (this->tag_limit_ != NoLimit)) {
res = this->countBasedResponseTag(this->increaseTagCount(tag));
}
if (res != Response::PrintMessage) {
// Tag count reached limit. Do not include message in
// category count.
return res;
}
// Tag count within limits. Include message in category count.
const auto count = this->increaseCategoryCount(messageMask);
if (const auto limitPos = this->category_limits_.find(messageMask);
(limitPos != this->category_limits_.end()) &&
(limitPos->second != NoLimit))
{
// There is a defined category limit for 'messageMask'.
// Generate response based on this limit.
res = this->countBasedResponseCategory(count, limitPos->second);
}
// PrintMessage or category based response.
return res;
}
int categoryMessageCount(const std::int64_t category) const
{
const auto countPos = this->category_counts_.find(category);
return (countPos != this->category_counts_.end())
? countPos->second : 0;
}
private:
int tag_limit_ {NoLimit};
std::map<std::int64_t, int> category_limits_{};
mutable std::unordered_map<std::string, int> tag_counts_{};
mutable std::map<std::int64_t, int> category_counts_{};
int increaseTagCount(const std::string& tag) const
{
return increaseCount(tag, this->tag_counts_);
}
int increaseCategoryCount(const std::int64_t messageMask) const
{
return increaseCount(messageMask, this->category_counts_);
}
Response countBasedResponseTag(const int count) const
{
return response(count, this->tag_limit_,
Response::JustOverTagLimit,
Response::OverTagLimit);
}
Response countBasedResponseCategory(const int count,
const int category_limit) const
{
return response(count, category_limit,
Response::JustOverCategoryLimit,
Response::OverCategoryLimit);
}
template <typename Key, class CountMap>
static int increaseCount(const Key& key, CountMap& counts)
{
return ++counts.try_emplace(key, 0).first->second;
}
static Response response(const int count,
const int limit,
const Response justOverLimit,
const Response overLimit)
{
if (count <= limit) {
return Response::PrintMessage;
} else if (count == limit + 1) {
return justOverLimit;
} else {
return overLimit;
}
}
};
} // namespace Opm
#endif // OPM_MESSAGELIMITER_HEADER_INCLUDED
Opm::MessageLimiter
Handles limiting the number of messages with the same tag.
Definition MessageLimiter.hpp:34
Opm::MessageLimiter::Response
Response
Used for handleMessageLimits() return type (see that function).
Definition MessageLimiter.hpp:41
Opm::MessageLimiter::Response::JustOverCategoryLimit
@ JustOverCategoryLimit
Message has reached the current limit for this category.
Definition MessageLimiter.hpp:49
Opm::MessageLimiter::Response::JustOverTagLimit
@ JustOverTagLimit
Message has reached the current limit for this tag.
Definition MessageLimiter.hpp:46
Opm::MessageLimiter::Response::OverTagLimit
@ OverTagLimit
Message is over the current limit for this tag.
Definition MessageLimiter.hpp:52
Opm::MessageLimiter::Response::OverCategoryLimit
@ OverCategoryLimit
Message is over the current limit of this category.
Definition MessageLimiter.hpp:55
Opm::MessageLimiter::Response::PrintMessage
@ PrintMessage
Message should be printed. Not affected by any limit.
Definition MessageLimiter.hpp:43
Opm::MessageLimiter::MessageLimiter
MessageLimiter(const int tag_limit)
Construct with given limit to number of messages with the same tag.
Definition MessageLimiter.hpp:67
Opm::MessageLimiter::tagMessageLimit
int tagMessageLimit() const
The tag message limit (same for all tags).
Definition MessageLimiter.hpp:77
Opm::MessageLimiter::categoryMessageCount
int categoryMessageCount(const std::int64_t category) const
Retrieve message count for specific category.
Definition MessageLimiter.hpp:128
Opm::MessageLimiter::handleMessageLimits
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
Opm::MessageLimiter::MessageLimiter
MessageLimiter()=default
Default constructor, no limit to the number of messages.
Opm
This class implements a small container which holds the transmissibility mulitpliers for all the face...
Definition Exceptions.hpp:30