diff options
23 files changed, 75 insertions, 56 deletions
diff --git a/messagebus/src/tests/simpleprotocol/simpleprotocol.cpp b/messagebus/src/tests/simpleprotocol/simpleprotocol.cpp index 715ef597767..091c7b668a1 100644 --- a/messagebus/src/tests/simpleprotocol/simpleprotocol.cpp +++ b/messagebus/src/tests/simpleprotocol/simpleprotocol.cpp @@ -6,9 +6,7 @@ #include <vespa/messagebus/testlib/simplereply.h> #include <vespa/messagebus/testlib/slobrok.h> #include <vespa/messagebus/testlib/testserver.h> -#include <vespa/messagebus/errorcode.h> #include <vespa/messagebus/ireplyhandler.h> -#include <vespa/messagebus/network/identity.h> #include <vespa/messagebus/routing/routingcontext.h> #include <vespa/vespalib/testkit/testapp.h> #include <vespa/vespalib/component/vtag.h> @@ -29,12 +27,15 @@ Test::Main() { // test protocol IRoutingPolicy::UP bogus = protocol.createPolicy("bogus", ""); - EXPECT_TRUE(bogus.get() == 0); + EXPECT_FALSE(bogus); } TEST_FLUSH(); { // test SimpleMessage - Message::UP msg(new SimpleMessage("test")); + EXPECT_EQUAL(160u, sizeof(Routable)); + EXPECT_EQUAL(208u, sizeof(Message)); + EXPECT_EQUAL(288u, sizeof(SimpleMessage)); + auto msg = std::make_unique<SimpleMessage>("test"); EXPECT_TRUE(!msg->isReply()); EXPECT_TRUE(msg->getProtocol() == SimpleProtocol::NAME); EXPECT_TRUE(msg->getType() == SimpleProtocol::MESSAGE); @@ -42,7 +43,7 @@ Test::Main() Blob b = protocol.encode(version, *msg); EXPECT_TRUE(b.size() > 0); Routable::UP tmp = protocol.decode(version, BlobRef(b)); - ASSERT_TRUE(tmp.get() != 0); + ASSERT_TRUE(tmp); EXPECT_TRUE(!tmp->isReply()); EXPECT_TRUE(tmp->getProtocol() == SimpleProtocol::NAME); EXPECT_TRUE(tmp->getType() == SimpleProtocol::MESSAGE); @@ -51,7 +52,10 @@ Test::Main() TEST_FLUSH(); { // test SimpleReply - Reply::UP reply(new SimpleReply("reply")); + EXPECT_EQUAL(160u, sizeof(Routable)); + EXPECT_EQUAL(200u, sizeof(Reply)); + EXPECT_EQUAL(264u, sizeof(SimpleReply)); + auto reply = std::make_unique<SimpleReply>("reply"); EXPECT_TRUE(reply->isReply()); EXPECT_TRUE(reply->getProtocol() == SimpleProtocol::NAME); EXPECT_TRUE(reply->getType() == SimpleProtocol::REPLY); @@ -59,7 +63,7 @@ Test::Main() Blob b = protocol.encode(version, *reply); EXPECT_TRUE(b.size() > 0); Routable::UP tmp = protocol.decode(version, BlobRef(b)); - ASSERT_TRUE(tmp.get() != 0); + ASSERT_TRUE(tmp); EXPECT_TRUE(tmp->isReply()); EXPECT_TRUE(tmp->getProtocol() == SimpleProtocol::NAME); EXPECT_TRUE(tmp->getType() == SimpleProtocol::REPLY); diff --git a/messagebus/src/vespa/messagebus/network/rpcsend.cpp b/messagebus/src/vespa/messagebus/network/rpcsend.cpp index dca7f0c997f..86c9b139f1a 100644 --- a/messagebus/src/vespa/messagebus/network/rpcsend.cpp +++ b/messagebus/src/vespa/messagebus/network/rpcsend.cpp @@ -178,7 +178,7 @@ RPCSend::doRequestDone(FRT_RPCRequest *req) { } } else { FRT_Values &ret = *req->GetReturn(); - reply = createReply(ret, serviceName, error, trace.getRoot()); + reply = createReply(ret, serviceName, error, trace); } if (trace.shouldTrace(TraceLevel::SEND_RECEIVE)) { trace.trace(TraceLevel::SEND_RECEIVE, diff --git a/messagebus/src/vespa/messagebus/network/rpcsend.h b/messagebus/src/vespa/messagebus/network/rpcsend.h index f3a9177d236..1ccdea6fbc5 100644 --- a/messagebus/src/vespa/messagebus/network/rpcsend.h +++ b/messagebus/src/vespa/messagebus/network/rpcsend.h @@ -12,7 +12,7 @@ class FRT_ReflectionBuilder; namespace vespalib::slime { struct Cursor; } namespace vespalib { struct Memory; } -namespace vespalib { class TraceNode; } +namespace vespalib { class Trace; } namespace mbus { class Error; @@ -56,7 +56,7 @@ protected: virtual void build(FRT_ReflectionBuilder & builder) = 0; virtual std::unique_ptr<Reply> createReply(const FRT_Values & response, const string & serviceName, - Error & error, vespalib::TraceNode & rootTrace) const = 0; + Error & error, vespalib::Trace & trace) const = 0; virtual void encodeRequest(FRT_RPCRequest &req, const vespalib::Version &version, const Route & route, const RPCServiceAddress & address, const Message & msg, uint32_t traceLevel, const PayLoadFiller &filler, duration timeRemaining) const = 0; diff --git a/messagebus/src/vespa/messagebus/network/rpcsendv1.cpp b/messagebus/src/vespa/messagebus/network/rpcsendv1.cpp index 388ab3309c4..f87a8d9638a 100644 --- a/messagebus/src/vespa/messagebus/network/rpcsendv1.cpp +++ b/messagebus/src/vespa/messagebus/network/rpcsendv1.cpp @@ -115,7 +115,7 @@ RPCSendV1::toParams(const FRT_Values &args) const std::unique_ptr<Reply> -RPCSendV1::createReply(const FRT_Values & ret, const string & serviceName, Error & error, vespalib::TraceNode & rootTrace) const +RPCSendV1::createReply(const FRT_Values & ret, const string & serviceName, Error & error, vespalib::Trace & trace) const { vespalib::Version version = vespalib::Version(ret[0]._string._str); double retryDelay = ret[1]._double; @@ -127,7 +127,7 @@ RPCSendV1::createReply(const FRT_Values & ret, const string & serviceName, Error uint32_t errorServicesLen = ret[4]._string_array._len; const char *protocolName = ret[5]._string._str; BlobRef payload(ret[6]._data._buf, ret[6]._data._len); - const char *trace = ret[7]._string._str; + const char *traceStr = ret[7]._string._str; Reply::UP reply; if (payload.size() > 0) { @@ -141,7 +141,7 @@ RPCSendV1::createReply(const FRT_Values & ret, const string & serviceName, Error reply->addError(Error(errorCodes[i], errorMessages[i]._str, errorServices[i]._len > 0 ? errorServices[i]._str : serviceName.c_str())); } - rootTrace.addChild(TraceNode::decode(trace)); + trace.addChild(TraceNode::decode(traceStr)); return reply; } diff --git a/messagebus/src/vespa/messagebus/network/rpcsendv1.h b/messagebus/src/vespa/messagebus/network/rpcsendv1.h index 249acc50e0c..f9b4b0bdfe8 100644 --- a/messagebus/src/vespa/messagebus/network/rpcsendv1.h +++ b/messagebus/src/vespa/messagebus/network/rpcsendv1.h @@ -17,7 +17,7 @@ private: const PayLoadFiller &filler, duration timeRemaining) const override; std::unique_ptr<Reply> createReply(const FRT_Values & response, const string & serviceName, - Error & error, vespalib::TraceNode & rootTrace) const override; + Error & error, vespalib::Trace & trace) const override; void createResponse(FRT_Values & ret, const string & version, Reply & reply, Blob payload) const override; }; diff --git a/messagebus/src/vespa/messagebus/network/rpcsendv2.cpp b/messagebus/src/vespa/messagebus/network/rpcsendv2.cpp index f7303ece20f..9f5aad920b4 100644 --- a/messagebus/src/vespa/messagebus/network/rpcsendv2.cpp +++ b/messagebus/src/vespa/messagebus/network/rpcsendv2.cpp @@ -188,7 +188,7 @@ RPCSendV2::toParams(const FRT_Values &args) const std::unique_ptr<Reply> RPCSendV2::createReply(const FRT_Values & ret, const string & serviceName, - Error & error, vespalib::TraceNode & rootTrace) const + Error & error, vespalib::Trace & rootTrace) const { uint8_t encoding = ret[3]._intval8; uint32_t uncompressedSize = ret[4]._intval32; diff --git a/messagebus/src/vespa/messagebus/network/rpcsendv2.h b/messagebus/src/vespa/messagebus/network/rpcsendv2.h index c48aa90a9fb..da4154e70a8 100644 --- a/messagebus/src/vespa/messagebus/network/rpcsendv2.h +++ b/messagebus/src/vespa/messagebus/network/rpcsendv2.h @@ -17,7 +17,7 @@ private: const PayLoadFiller &filler, duration timeRemaining) const override; std::unique_ptr<Reply> createReply(const FRT_Values & response, const string & serviceName, - Error & error, vespalib::TraceNode & rootTrace) const override; + Error & error, vespalib::Trace & trace) const override; void createResponse(FRT_Values & ret, const string & version, Reply & reply, Blob payload) const override; }; diff --git a/messagebus/src/vespa/messagebus/routing/routingnode.cpp b/messagebus/src/vespa/messagebus/routing/routingnode.cpp index 3a433b05bc5..cc8dd236428 100644 --- a/messagebus/src/vespa/messagebus/routing/routingnode.cpp +++ b/messagebus/src/vespa/messagebus/routing/routingnode.cpp @@ -184,10 +184,7 @@ RoutingNode::setReply(Reply::UP reply) { if (reply) { _shouldRetry = _resender != nullptr && _resender->shouldRetry(*reply); - if ( ! reply->getTrace().isEmpty()) { - _trace.getRoot().addChild(std::move(reply->getTrace().getRoot())); - reply->getTrace().clear(); - } + _trace.addChild(std::move(reply->getTrace())); } _reply = std::move(reply); } @@ -268,14 +265,12 @@ RoutingNode::notifyMerge() // Merges the trace information from all children into this. This method takes care not to spend cycles // manipulating the trace in case tracing is disabled. if (_trace.getLevel() > 0) { - TraceNode tail; + Trace tail; for (auto * child : _children) { - TraceNode &root = child->_trace.getRoot(); - tail.addChild(root); - root.clear(); + tail.addChild(std::move(child->_trace)); } tail.setStrict(false); - _trace.getRoot().addChild(tail); + _trace.addChild(std::move(tail)); } // Execute the {@link RoutingPolicy#merge(RoutingContext)} method of the current routing policy. If a diff --git a/messagebus/src/vespa/messagebus/sendproxy.cpp b/messagebus/src/vespa/messagebus/sendproxy.cpp index fa485e19bb8..bec000b56e2 100644 --- a/messagebus/src/vespa/messagebus/sendproxy.cpp +++ b/messagebus/src/vespa/messagebus/sendproxy.cpp @@ -55,8 +55,8 @@ SendProxy::handleReply(Reply::UP reply) } trace.clear(); } else if (trace.getLevel() > 0) { - trace.getRoot().addChild(reply->getTrace().getRoot()); - trace.getRoot().normalize(); + trace.addChild(reply->getTrace().getRoot()); + trace.normalize(); } reply->swapState(*_msg); reply->setMessage(std::move(_msg)); diff --git a/messagebus_test/src/tests/trace/trace.cpp b/messagebus_test/src/tests/trace/trace.cpp index 334f00745da..ae051c4ecab 100644 --- a/messagebus_test/src/tests/trace/trace.cpp +++ b/messagebus_test/src/tests/trace/trace.cpp @@ -100,12 +100,12 @@ Test::Main() Reply::UP reply; SourceSession::UP ss = mb.getMessageBus().createSourceSession(src, SourceSessionParams()); for (int i = 0; i < 50; ++i) { - Message::UP msg(new SimpleMessage("test")); + auto msg = std::make_unique<SimpleMessage>("test"); msg->getTrace().setLevel(1); ss->send(std::move(msg), "test"); reply = src.getReply(10s); if (reply) { - reply->getTrace().getRoot().normalize(); + reply->getTrace().normalize(); // resending breaks the trace, so retry until it has expected form if (!reply->hasErrors() && reply->getTrace().getRoot().encode() == expect.encode()) { break; diff --git a/storage/src/tests/visiting/memory_bounded_trace_test.cpp b/storage/src/tests/visiting/memory_bounded_trace_test.cpp index 543531ef55a..d0ea1172e11 100644 --- a/storage/src/tests/visiting/memory_bounded_trace_test.cpp +++ b/storage/src/tests/visiting/memory_bounded_trace_test.cpp @@ -32,12 +32,12 @@ TEST(MemoryBoundedTraceTest, memory_used_is_accumulated_recursively_for_non_leaf TEST(MemoryBoundedTraceTest, trace_nodes_can_be_moved_and_implicitly_cleared) { MemoryBoundedTrace trace(100); EXPECT_TRUE(trace.add(mbus::TraceNode("hello world", epoch))); - mbus::TraceNode target; + mbus::Trace target; trace.moveTraceTo(target); EXPECT_EQ(1, target.getNumChildren()); EXPECT_EQ(0, trace.getApproxMemoryUsed()); - mbus::TraceNode emptinessCheck; + mbus::Trace emptinessCheck; trace.moveTraceTo(emptinessCheck); EXPECT_EQ(0, emptinessCheck.getNumChildren()); } @@ -52,10 +52,10 @@ TEST(MemoryBoundedTraceTest, trace_nodes_can_be_moved_and_implicitly_cleared) { TEST(MemoryBoundedTraceTest, moved_trace_tree_is_marked_as_strict) { MemoryBoundedTrace trace(100); EXPECT_TRUE(trace.add(mbus::TraceNode("hello world", epoch))); - mbus::TraceNode target; + mbus::Trace target; trace.moveTraceTo(target); EXPECT_EQ(1, target.getNumChildren()); - EXPECT_TRUE(target.getChild(0).isStrict()); + EXPECT_TRUE(target.getRoot().getChild(0).isStrict()); } TEST(MemoryBoundedTraceTest, can_not_add_more_nodes_when_memory_used_exceeds_upper_bound) { @@ -69,7 +69,7 @@ TEST(MemoryBoundedTraceTest, can_not_add_more_nodes_when_memory_used_exceeds_upp "the freeway", epoch))); EXPECT_EQ(11, trace.getApproxMemoryUsed()); - mbus::TraceNode target; + mbus::Trace target; trace.moveTraceTo(target); // Twice nested node (root -> added trace tree -> leaf with txt). EXPECT_EQ(1, target.getNumChildren()); @@ -82,7 +82,7 @@ TEST(MemoryBoundedTraceTest, moved_tree_includes_stats_node_when_nodes_omitted) EXPECT_TRUE(trace.add(mbus::TraceNode("abcdef", epoch))); EXPECT_FALSE(trace.add(mbus::TraceNode("ghijkjlmn", epoch))); - mbus::TraceNode target; + mbus::Trace target; trace.moveTraceTo(target); EXPECT_EQ(1, target.getNumChildren()); EXPECT_EQ(2, target.getChild(0).getNumChildren()); diff --git a/storage/src/vespa/storage/distributor/operations/external/getoperation.cpp b/storage/src/vespa/storage/distributor/operations/external/getoperation.cpp index cf7a0e4741e..9eff0b59e6e 100644 --- a/storage/src/vespa/storage/distributor/operations/external/getoperation.cpp +++ b/storage/src/vespa/storage/distributor/operations/external/getoperation.cpp @@ -145,7 +145,7 @@ GetOperation::onReceive(DistributorMessageSender& sender, const std::shared_ptr< LOG(debug, "Received %s", msg->toString(true).c_str()); if ( ! getreply->getTrace().isEmpty()) { - _msg->getTrace().getRoot().addChild(getreply->getTrace().getRoot()); + _msg->getTrace().addChild(getreply->getTrace().getRoot()); } bool allDone = true; for (auto& response : _responses) { diff --git a/storage/src/vespa/storage/distributor/operations/external/twophaseupdateoperation.cpp b/storage/src/vespa/storage/distributor/operations/external/twophaseupdateoperation.cpp index 0b7d035ec0d..d406855e856 100644 --- a/storage/src/vespa/storage/distributor/operations/external/twophaseupdateoperation.cpp +++ b/storage/src/vespa/storage/distributor/operations/external/twophaseupdateoperation.cpp @@ -133,7 +133,7 @@ TwoPhaseUpdateOperation::sendReply( { assert(!_replySent); if (!_trace.isEmpty()) { - reply->getTrace().getRoot().addChild(_trace); + reply->getTrace().addChild(_trace); } sender.sendReply(reply); _replySent = true; diff --git a/storage/src/vespa/storage/distributor/operations/external/visitoroperation.cpp b/storage/src/vespa/storage/distributor/operations/external/visitoroperation.cpp index 5a03e05d563..bbed631951c 100644 --- a/storage/src/vespa/storage/distributor/operations/external/visitoroperation.cpp +++ b/storage/src/vespa/storage/distributor/operations/external/visitoroperation.cpp @@ -828,8 +828,8 @@ VisitorOperation::sendReply(const api::ReturnCode& code, DistributorMessageSende { if (!_sentReply) { // Send create visitor reply - api::CreateVisitorReply::SP reply(new api::CreateVisitorReply(*_msg)); - _trace.moveTraceTo(reply->getTrace().getRoot()); + auto reply = std::make_shared<api::CreateVisitorReply>(*_msg); + _trace.moveTraceTo(reply->getTrace()); reply->setLastBucket(getLastBucketVisited()); reply->setResult(code); diff --git a/storage/src/vespa/storage/distributor/persistencemessagetracker.cpp b/storage/src/vespa/storage/distributor/persistencemessagetracker.cpp index 6253beda6e1..8f824e6a364 100644 --- a/storage/src/vespa/storage/distributor/persistencemessagetracker.cpp +++ b/storage/src/vespa/storage/distributor/persistencemessagetracker.cpp @@ -230,7 +230,7 @@ PersistenceMessageTrackerImpl::sendReply(MessageSender& sender) updateMetrics(); _trace.setStrict(false); if ( ! _trace.isEmpty()) { - _reply->getTrace().getRoot().addChild(_trace); + _reply->getTrace().addChild(_trace); } sender.sendReply(_reply); diff --git a/storage/src/vespa/storage/persistence/filestorage/filestormanager.cpp b/storage/src/vespa/storage/persistence/filestorage/filestormanager.cpp index cba3969cd68..6b6de2c8d83 100644 --- a/storage/src/vespa/storage/persistence/filestorage/filestormanager.cpp +++ b/storage/src/vespa/storage/persistence/filestorage/filestormanager.cpp @@ -676,7 +676,7 @@ FileStorManager::onInternal(const shared_ptr<api::InternalCommand>& msg) spi::Context context(msg->getLoadType(), msg->getPriority(), msg->getTrace().getLevel()); shared_ptr<DestroyIteratorCommand> cmd(std::static_pointer_cast<DestroyIteratorCommand>(msg)); _provider->destroyIterator(cmd->getIteratorId(), context); - msg->getTrace().getRoot().addChild(context.getTrace().getRoot()); + msg->getTrace().addChild(context.getTrace().getRoot()); return true; } case ReadBucketList::ID: diff --git a/storage/src/vespa/storage/persistence/persistenceutil.cpp b/storage/src/vespa/storage/persistence/persistenceutil.cpp index 37ef4c39597..af070281c4f 100644 --- a/storage/src/vespa/storage/persistence/persistenceutil.cpp +++ b/storage/src/vespa/storage/persistence/persistenceutil.cpp @@ -94,7 +94,7 @@ MessageTracker::sendReply() { } if (hasReply()) { if ( ! _context.getTrace().isEmpty()) { - getReply().getTrace().getRoot().addChild(_context.getTrace().getRoot()); + getReply().getTrace().addChild(_context.getTrace().getRoot()); } if (_updateBucketInfo) { if (getReply().getResult().success()) { @@ -109,7 +109,7 @@ MessageTracker::sendReply() { _replySender.sendReplyDirectly(std::move(_reply)); } else { if ( ! _context.getTrace().isEmpty()) { - _msg->getTrace().getRoot().addChild(_context.getTrace().getRoot()); + _msg->getTrace().addChild(_context.getTrace().getRoot()); } } } diff --git a/storage/src/vespa/storage/storageserver/rpc/storage_api_rpc_service.cpp b/storage/src/vespa/storage/storageserver/rpc/storage_api_rpc_service.cpp index cb1d0380bf1..eaba3d54c27 100644 --- a/storage/src/vespa/storage/storageserver/rpc/storage_api_rpc_service.cpp +++ b/storage/src/vespa/storage/storageserver/rpc/storage_api_rpc_service.cpp @@ -289,7 +289,7 @@ void StorageApiRpcService::RequestDone(FRT_RPCRequest* raw_req) { assert(reply); if (!hdr.trace_payload().empty()) { - cmd.getTrace().getRoot().addChild(mbus::TraceNode::decode(hdr.trace_payload())); + cmd.getTrace().addChild(mbus::TraceNode::decode(hdr.trace_payload())); } if (cmd.getTrace().shouldTrace(TraceLevel::SEND_RECEIVE)) { cmd.getTrace().trace(TraceLevel::SEND_RECEIVE, diff --git a/storage/src/vespa/storage/visiting/memory_bounded_trace.cpp b/storage/src/vespa/storage/visiting/memory_bounded_trace.cpp index 9f9eb2942c1..77eb7bd18b8 100644 --- a/storage/src/vespa/storage/visiting/memory_bounded_trace.cpp +++ b/storage/src/vespa/storage/visiting/memory_bounded_trace.cpp @@ -48,7 +48,7 @@ MemoryBoundedTrace::add(const mbus::TraceNode& node) } void -MemoryBoundedTrace::moveTraceTo(mbus::TraceNode& out) +MemoryBoundedTrace::moveTraceTo(mbus::Trace& out) { if (_node.isEmpty()) { return; diff --git a/storage/src/vespa/storage/visiting/memory_bounded_trace.h b/storage/src/vespa/storage/visiting/memory_bounded_trace.h index 71ce1be51ac..1c20e56cae0 100644 --- a/storage/src/vespa/storage/visiting/memory_bounded_trace.h +++ b/storage/src/vespa/storage/visiting/memory_bounded_trace.h @@ -33,7 +33,7 @@ public: * * If current trace is empty, no nodes are added to `out`. */ - void moveTraceTo(mbus::TraceNode& out); + void moveTraceTo(mbus::Trace& out); size_t getApproxMemoryUsed() const noexcept { return _currentMemoryUsed; diff --git a/storage/src/vespa/storage/visiting/visitor.cpp b/storage/src/vespa/storage/visiting/visitor.cpp index 2684ca03462..540020e978b 100644 --- a/storage/src/vespa/storage/visiting/visitor.cpp +++ b/storage/src/vespa/storage/visiting/visitor.cpp @@ -371,10 +371,9 @@ Visitor::sendReplyOnce() std::shared_ptr<api::StorageReply> reply(_initiatingCmd->makeReply()); _hitCounter->updateVisitorStatistics(_visitorStatistics); - static_cast<api::CreateVisitorReply*>(reply.get()) - ->setVisitorStatistics(_visitorStatistics); + static_cast<api::CreateVisitorReply*>(reply.get())->setVisitorStatistics(_visitorStatistics); if (shouldAddMbusTrace()) { - _trace.moveTraceTo(reply->getTrace().getRoot()); + _trace.moveTraceTo(reply->getTrace()); } reply->setResult(_result); LOG(debug, "Sending %s", reply->toString(true).c_str()); diff --git a/vespalib/src/tests/trace/trace.cpp b/vespalib/src/tests/trace/trace.cpp index 92bee3231b0..9e9318bf4b8 100644 --- a/vespalib/src/tests/trace/trace.cpp +++ b/vespalib/src/tests/trace/trace.cpp @@ -261,7 +261,7 @@ TEST("testTraceDump") b1.addChild(b2); } for (int i = 0; i < 10; ++i) { - big.getRoot().addChild(b1); + big.addChild(b1); } string normal = big.toString(); string full = big.getRoot().toString(); diff --git a/vespalib/src/vespa/vespalib/trace/trace.h b/vespalib/src/vespa/vespalib/trace/trace.h index 6676be4a81e..bad89bf6646 100644 --- a/vespalib/src/vespa/vespalib/trace/trace.h +++ b/vespalib/src/vespa/vespalib/trace/trace.h @@ -18,9 +18,6 @@ namespace vespalib { * information will be traced. */ class Trace { -private: - TraceNode _root; - uint32_t _level; public: /** @@ -100,12 +97,28 @@ public: */ bool trace(uint32_t level, const string ¬e, bool addTime = true); + void normalize() { + _root.normalize(); + } + /** - * Returns the root of the trace tree. + * Adds a child node to this. * - * @return The root. + * @param child The child to add. + * @return This, to allow chaining. */ - TraceNode &getRoot() { return _root; } + void addChild(TraceNode child) { + ensureRoot().addChild(std::move(child)); + } + + void setStrict(bool strict) { + ensureRoot().setStrict(strict); + } + void addChild(Trace && child) { + if (!child.isEmpty()) { + addChild(std::move(child._root)); + } + } /** * Returns a const reference to the root of the trace tree. @@ -116,6 +129,9 @@ public: bool isEmpty() const { return _root.isEmpty(); } + uint32_t getNumChildren() const { return _root.getNumChildren(); } + const TraceNode & getChild(uint32_t child) const { return getRoot().getChild(child); } + /** * Returns a string representation of the contained trace tree. This is a * readable, non-parseable string. @@ -123,6 +139,11 @@ public: * @return Readable trace string. */ string toString() const { return _root.toString(31337); } +private: + TraceNode &ensureRoot() { return _root; } + + TraceNode _root; + uint32_t _level; }; #define VESPALIB_TRACE2(ttrace, level, note, addTime) \ |