2016-05-18 05:11:26 -05:00
|
|
|
/*
|
|
|
|
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
|
|
|
|
|
2016-10-19 06:11:13 -05:00
|
|
|
#include <opm/common/OpmLog/LogUtil.hpp>
|
|
|
|
#include <cassert>
|
|
|
|
#include <map>
|
2016-05-18 05:11:26 -05:00
|
|
|
#include <string>
|
|
|
|
#include <unordered_map>
|
2016-10-18 06:26:06 -05:00
|
|
|
#include <vector>
|
2016-10-19 06:11:13 -05:00
|
|
|
|
|
|
|
|
2016-05-18 05:11:26 -05:00
|
|
|
namespace Opm
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
/// Handles limiting the number of messages with the same tag.
|
|
|
|
class MessageLimiter
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
/// Used to indicate no message number limit.
|
|
|
|
enum { NoLimit = -1 };
|
|
|
|
|
|
|
|
/// Default constructor, no limit to the number of messages.
|
|
|
|
MessageLimiter()
|
2016-10-19 06:11:13 -05:00
|
|
|
: MessageLimiter(NoLimit)
|
2016-05-18 05:11:26 -05:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Construct with given limit to number of messages with the
|
|
|
|
/// same tag.
|
|
|
|
///
|
|
|
|
/// Negative limits (including NoLimit) are interpreted as
|
|
|
|
/// NoLimit, but the default constructor is the preferred way
|
|
|
|
/// to obtain that behaviour.
|
2016-10-18 06:26:06 -05:00
|
|
|
explicit MessageLimiter(const int tag_limit)
|
|
|
|
: tag_limit_(tag_limit < 0 ? NoLimit : tag_limit),
|
|
|
|
category_limits_({{Log::MessageType::Note, NoLimit},
|
|
|
|
{Log::MessageType::Info, NoLimit},
|
|
|
|
{Log::MessageType::Warning, NoLimit},
|
|
|
|
{Log::MessageType::Error, NoLimit},
|
|
|
|
{Log::MessageType::Problem, NoLimit},
|
|
|
|
{Log::MessageType::Bug, NoLimit}})
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
MessageLimiter(const int tag_limit, const std::map<int64_t, int> category_limits)
|
|
|
|
: tag_limit_(tag_limit < 0 ? NoLimit : tag_limit),
|
|
|
|
category_limits_(category_limits)
|
2016-05-18 05:11:26 -05:00
|
|
|
{
|
2016-10-19 08:08:46 -05:00
|
|
|
// Must ensure NoLimit for categories that are not
|
|
|
|
// explicitly specified in the input.
|
|
|
|
for (auto category : { Log::MessageType::Note,
|
|
|
|
Log::MessageType::Info,
|
|
|
|
Log::MessageType::Warning,
|
|
|
|
Log::MessageType::Error,
|
|
|
|
Log::MessageType::Problem,
|
|
|
|
Log::MessageType::Bug }) {
|
|
|
|
if (category_limits_.find(category) == category_limits_.end()) {
|
|
|
|
category_limits_[category] = NoLimit;
|
|
|
|
}
|
|
|
|
}
|
2016-05-18 05:11:26 -05:00
|
|
|
}
|
|
|
|
|
2016-10-19 06:11:13 -05:00
|
|
|
/// The tag message limit (same for all tags).
|
|
|
|
int tagMessageLimit() const
|
2016-05-18 05:11:26 -05:00
|
|
|
{
|
2016-10-18 06:26:06 -05:00
|
|
|
return tag_limit_;
|
2016-05-18 05:11:26 -05:00
|
|
|
}
|
|
|
|
|
2016-10-19 06:11:13 -05:00
|
|
|
/// The category message limits.
|
|
|
|
const std::map<int64_t, int>& categoryMessageLimits() const
|
|
|
|
{
|
|
|
|
return category_limits_;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// The category message counts.
|
|
|
|
const std::map<int64_t, int>& categoryMessageCounts() const
|
|
|
|
{
|
|
|
|
return category_counts_;
|
|
|
|
}
|
|
|
|
|
2016-10-18 06:26:06 -05:00
|
|
|
/// Used for handleMessageLimits() return type (see that
|
2016-05-18 05:11:26 -05:00
|
|
|
/// function).
|
|
|
|
enum class Response
|
|
|
|
{
|
2016-10-18 06:26:06 -05:00
|
|
|
PrintMessage, JustOverTagLimit, JustOverCategoryLimit, OverTagLimit, OverCategoryLimit
|
2016-05-18 05:11:26 -05:00
|
|
|
};
|
|
|
|
|
2016-10-19 06:11:13 -05:00
|
|
|
/// If (tag count == tag limit + 1) for the passed tag, respond JustOverTagLimit.
|
|
|
|
/// If (tag count > tag limit + 1), respond OverTagLimit.
|
|
|
|
/// If a tag is empty, there is no tag message limit or for that tag
|
|
|
|
/// (tag count <= tag limit), consider the category limits:
|
|
|
|
/// If (category count == category limit + 1) for the passed messageMask, respond JustOverCategoryLimit.
|
|
|
|
/// If (category count > category limit + 1), respond OverCategoryLimit.
|
|
|
|
/// If (category count <= category limit), or there is no limit for that category, respond PrintMessage.
|
2016-10-18 06:26:06 -05:00
|
|
|
Response handleMessageLimits(const std::string& tag, const int64_t messageMask)
|
2016-05-18 05:11:26 -05:00
|
|
|
{
|
2016-10-18 06:26:06 -05:00
|
|
|
Response res = Response::PrintMessage;
|
2016-10-19 06:11:13 -05:00
|
|
|
|
2016-10-18 06:26:06 -05:00
|
|
|
// Deal with tag limits.
|
2016-10-19 06:11:13 -05:00
|
|
|
if (!tag.empty() && tag_limit_ != NoLimit) {
|
2016-05-18 05:11:26 -05:00
|
|
|
// See if tag already encountered.
|
|
|
|
auto it = tag_counts_.find(tag);
|
|
|
|
if (it != tag_counts_.end()) {
|
|
|
|
// Already encountered this tag. Increment its count.
|
|
|
|
const int count = ++it->second;
|
2016-10-19 06:11:13 -05:00
|
|
|
res = countBasedResponseTag(count);
|
2016-05-18 05:11:26 -05:00
|
|
|
} else {
|
|
|
|
// First encounter of this tag. Insert 1.
|
|
|
|
tag_counts_.insert({tag, 1});
|
2016-10-19 06:11:13 -05:00
|
|
|
res = countBasedResponseTag(1);
|
2016-05-18 05:11:26 -05:00
|
|
|
}
|
|
|
|
}
|
2016-10-19 06:11:13 -05:00
|
|
|
|
|
|
|
// If tag count reached the limit, the message is not counted
|
|
|
|
// towards the category limits.
|
|
|
|
if (res == Response::PrintMessage) {
|
|
|
|
// We are *not* above the tag limit, consider category limit.
|
|
|
|
const int count = ++category_counts_[messageMask];
|
|
|
|
if (category_limits_[messageMask] != NoLimit) {
|
|
|
|
res = countBasedResponseCategory(count, messageMask);
|
2016-10-18 06:26:06 -05:00
|
|
|
}
|
|
|
|
}
|
2016-10-19 06:11:13 -05:00
|
|
|
|
2016-10-18 06:26:06 -05:00
|
|
|
return res;
|
2016-05-18 05:11:26 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2016-10-19 06:11:13 -05:00
|
|
|
Response countBasedResponseTag(const int count) const
|
2016-05-18 05:11:26 -05:00
|
|
|
{
|
2016-10-18 06:26:06 -05:00
|
|
|
if (count <= tag_limit_) {
|
2016-05-18 05:11:26 -05:00
|
|
|
return Response::PrintMessage;
|
2016-10-18 06:26:06 -05:00
|
|
|
} else if (count == tag_limit_ + 1) {
|
|
|
|
return Response::JustOverTagLimit;
|
2016-05-18 05:11:26 -05:00
|
|
|
} else {
|
2016-10-18 06:26:06 -05:00
|
|
|
return Response::OverTagLimit;
|
2016-05-18 05:11:26 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-10-19 06:11:13 -05:00
|
|
|
Response countBasedResponseCategory(const int count, const int64_t messageMask) const
|
2016-10-18 06:26:06 -05:00
|
|
|
{
|
2016-10-19 06:11:13 -05:00
|
|
|
const int limit = category_limits_.at(messageMask);
|
|
|
|
if (count <= limit) {
|
2016-10-18 06:26:06 -05:00
|
|
|
return Response::PrintMessage;
|
2016-10-19 06:11:13 -05:00
|
|
|
} else if (count == limit + 1) {
|
2016-10-18 06:26:06 -05:00
|
|
|
return Response::JustOverCategoryLimit;
|
|
|
|
} else {
|
|
|
|
return Response::OverCategoryLimit;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int tag_limit_;
|
2016-05-18 05:11:26 -05:00
|
|
|
std::unordered_map<std::string, int> tag_counts_;
|
2016-10-18 06:26:06 -05:00
|
|
|
std::map<int64_t, int> category_limits_;
|
2016-10-19 06:11:13 -05:00
|
|
|
std::map<int64_t, int> category_counts_ = {{Log::MessageType::Note, 0},
|
|
|
|
{Log::MessageType::Info, 0},
|
|
|
|
{Log::MessageType::Warning, 0},
|
|
|
|
{Log::MessageType::Error, 0},
|
|
|
|
{Log::MessageType::Problem, 0},
|
|
|
|
{Log::MessageType::Bug, 0}};
|
2016-05-18 05:11:26 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} // namespace Opm
|
|
|
|
|
|
|
|
#endif // OPM_MESSAGELIMITER_HEADER_INCLUDED
|