Compare commits

...
Author SHA1 Message Date
Mayukha Vadari bfcc6620df perf: Build a log sink only for a new partition
Logs::get called sinks_.emplace(name, makeSink(name, thresh_)), which
evaluates makeSink() and so allocates a sink on every call, then drops
it when the partition already exists. Every getJournal() call paid for
that allocation under the mutex. Look the partition up first and build
a sink only when it is missing.
2026-10-12 13:54:09 -04:00
2 changed files with 52 additions and 2 deletions

No files matched your search

+6 -2
View File
@@ -123,8 +123,12 @@ beast::Journal::Sink&
Logs::get(std::string const& name)
{
std::scoped_lock const lock(mutex_);
auto const result = sinks_.emplace(name, makeSink(name, thresh_));
return *result.first->second;
// Look up first: emplace() would evaluate makeSink(), and so allocate a
// sink, on every call even when the partition already has one.
auto it = sinks_.find(name);
if (it == sinks_.end())
it = sinks_.emplace(name, makeSink(name, thresh_)).first;
return *it->second;
}
beast::Journal::Sink&
+46
View File
@@ -0,0 +1,46 @@
#include <xrpl/basics/Log.h>
#include <xrpl/beast/utility/Journal.h>
#include <gtest/gtest.h>
#include <memory>
#include <string>
using namespace xrpl;
namespace {
class CountingLogs : public Logs
{
public:
int made = 0;
CountingLogs() : Logs(beast::Severity::Warning)
{
}
std::unique_ptr<beast::Journal::Sink>
makeSink(std::string const& partition, beast::Severity threshold) override
{
++made;
return Logs::makeSink(partition, threshold);
}
};
} // namespace
TEST(LogsTest, get_makes_one_sink_per_partition)
{
CountingLogs logs;
beast::Journal::Sink const& first = logs.get("View");
EXPECT_EQ(logs.made, 1);
// Same partition, any case: same sink, and no new one is built.
EXPECT_EQ(&logs.get("View"), &first);
EXPECT_EQ(&logs.get("view"), &first);
EXPECT_EQ(logs.made, 1);
EXPECT_NE(&logs.get("Ledger"), &first);
EXPECT_EQ(logs.made, 2);
}