mirror of
https://github.com/Icinga/icinga2.git
synced 2026-06-11 09:40:46 -04:00
Change RedisConnection::Query::value_type to a string/view variant
Especially our history messages contain lots of hardcoded C string literals `"like this one"`. At runtime, they get translated to pointers to constant global memory, `const char*`. String `malloc(3)`s and copies these data every time. In contrast, the new type just stores the address if any. (Actually, `const char*` is wrapped by `std::string_view` to not compute its length every time.)
This commit is contained in:
parent
c351f6a88c
commit
1702eebd41
3 changed files with 58 additions and 9 deletions
|
|
@ -697,7 +697,7 @@ void IcingaDB::InsertObjectDependencies(const ConfigObject::Ptr& object, const S
|
|||
actionUrls.emplace_back(JsonEncode(data));
|
||||
|
||||
if (runtimeUpdate) {
|
||||
AddObjectDataToRuntimeUpdates(runtimeUpdates, actionUrls.at(actionUrls.size() - 2u), m_PrefixConfigObject + "action:url", data);
|
||||
AddObjectDataToRuntimeUpdates(runtimeUpdates, static_cast<String>(actionUrls.at(actionUrls.size() - 2u)), m_PrefixConfigObject + "action:url", data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -712,7 +712,7 @@ void IcingaDB::InsertObjectDependencies(const ConfigObject::Ptr& object, const S
|
|||
notesUrls.emplace_back(JsonEncode(data));
|
||||
|
||||
if (runtimeUpdate) {
|
||||
AddObjectDataToRuntimeUpdates(runtimeUpdates, notesUrls.at(notesUrls.size() - 2u), m_PrefixConfigObject + "notes:url", data);
|
||||
AddObjectDataToRuntimeUpdates(runtimeUpdates, static_cast<String>(notesUrls.at(notesUrls.size() - 2u)), m_PrefixConfigObject + "notes:url", data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -727,7 +727,7 @@ void IcingaDB::InsertObjectDependencies(const ConfigObject::Ptr& object, const S
|
|||
iconImages.emplace_back(JsonEncode(data));
|
||||
|
||||
if (runtimeUpdate) {
|
||||
AddObjectDataToRuntimeUpdates(runtimeUpdates, iconImages.at(iconImages.size() - 2u), m_PrefixConfigObject + "icon:image", data);
|
||||
AddObjectDataToRuntimeUpdates(runtimeUpdates, static_cast<String>(iconImages.at(iconImages.size() - 2u)), m_PrefixConfigObject + "icon:image", data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -94,14 +94,14 @@ void LogQuery(RedisConnection::Query& query, Log& msg)
|
|||
{
|
||||
int i = 0;
|
||||
|
||||
for (auto& arg : query) {
|
||||
for (std::string_view arg : query) {
|
||||
if (++i == 8) {
|
||||
msg << " ...";
|
||||
break;
|
||||
}
|
||||
|
||||
if (arg.GetLength() > 64) {
|
||||
msg << " '" << arg.SubStr(0, 61) << "...'";
|
||||
if (arg.length() > 64) {
|
||||
msg << " '" << arg.substr(0, 61) << "...'";
|
||||
} else {
|
||||
msg << " '" << arg << '\'';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,7 +39,9 @@
|
|||
#include <queue>
|
||||
#include <set>
|
||||
#include <stdexcept>
|
||||
#include <string_view>
|
||||
#include <utility>
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
|
||||
namespace icinga
|
||||
|
|
@ -54,7 +56,54 @@ namespace icinga
|
|||
public:
|
||||
DECLARE_PTR_TYPEDEFS(RedisConnection);
|
||||
|
||||
typedef String QueryArg;
|
||||
/**
|
||||
* A Redis query argument. Either owned String or hardcoded const char[].
|
||||
* Allows mixing these types in a single query transparently, not requiring any conversions.
|
||||
*
|
||||
* @ingroup icingadb
|
||||
*/
|
||||
class QueryArg
|
||||
{
|
||||
public:
|
||||
QueryArg(const char data[]) noexcept : m_Data(std::in_place_type<std::string_view>, data)
|
||||
{
|
||||
}
|
||||
|
||||
QueryArg(String data) noexcept : m_Data(std::move(data))
|
||||
{
|
||||
}
|
||||
|
||||
bool operator<(const QueryArg& rhs) const noexcept // For std::map keys
|
||||
{
|
||||
return static_cast<std::string_view>(*this) < static_cast<std::string_view>(rhs);
|
||||
}
|
||||
|
||||
operator std::string_view() const noexcept
|
||||
{
|
||||
return std::visit([](auto& data) { return ViewOf(data); }, m_Data);
|
||||
}
|
||||
|
||||
explicit operator String() const
|
||||
{
|
||||
std::string_view sv (*this);
|
||||
|
||||
return String(sv.begin(), sv.end());
|
||||
}
|
||||
|
||||
private:
|
||||
std::variant<std::string_view, String> m_Data;
|
||||
|
||||
static std::string_view ViewOf(const std::string_view& data) noexcept
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
static std::string_view ViewOf(const String& data) noexcept
|
||||
{
|
||||
return {data.CStr(), data.GetLength()};
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::vector<QueryArg> Query;
|
||||
typedef std::vector<Query> Queries;
|
||||
typedef Value Reply;
|
||||
|
|
@ -665,8 +714,8 @@ void RedisConnection::WriteRESP(AsyncWriteStream& stream, const Query& query, bo
|
|||
|
||||
msg << "*" << query.size() << "\r\n";
|
||||
|
||||
for (auto& arg : query) {
|
||||
msg << "$" << arg.GetLength() << "\r\n" << arg << "\r\n";
|
||||
for (std::string_view arg : query) {
|
||||
msg << "$" << arg.length() << "\r\n" << arg << "\r\n";
|
||||
}
|
||||
|
||||
asio::async_write(stream, writeBuffer, yc);
|
||||
|
|
|
|||
Loading…
Reference in a new issue