* -------------------------------------------------------------------------
* This file is part of the MindStudio project.
* Copyright (c) 2025 Huawei Technologies Co.,Ltd.
*
* MindStudio is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
* -------------------------------------------------------------------------
*/
#ifndef PROFILER_SERVER_MEM_SCOPE_PROTOCOL_RESPONSE_H
#define PROFILER_SERVER_MEM_SCOPE_PROTOCOL_RESPONSE_H
#include <vector>
#include "GlobalDefs.h"
#include "ProtocolDefs.h"
#include "ProtocolMessage.h"
#include "CommonRequests.h"
#include "MemScopeDefs.h"
#include "MemScopeEntities.h"
#include "MemScopeTableColumn.h"
#include "MemScopeEventTree.h"
namespace Dic::Protocol {
using namespace Dic::Module;
using namespace Dic::Module::MemScope;
static document_t ToMemScopeMemoryBlockJson(const MemoryBlock &block, Document::AllocatorType &allocator) {
document_t json(kObjectType);
JsonUtil::AddMember(json, "id", block.id, allocator);
JsonUtil::AddMember(json, "addr", block.ptr, allocator);
JsonUtil::AddMember(json, "size", block.size, allocator);
JsonUtil::AddMember(json, "_startTimestamp", block.startTimestamp, allocator);
JsonUtil::AddMember(json, "_endTimestamp", block.endTimestamp, allocator);
JsonUtil::AddMember(json, "owner", block.owner, allocator);
JsonUtil::AddMember(json, "attr", block.attrJsonString, allocator);
JsonUtil::AddMember(json, "processId", block.processId, allocator);
JsonUtil::AddMember(json, "threadId", block.threadId, allocator);
JsonUtil::AddMember(json, "deviceId", block.deviceId, allocator);
JsonUtil::AddMember(json, "eventType", block.eventType, allocator);
JsonUtil::AddMember(json, "_firstAccessTimestamp", block.firstAccessTimestamp, allocator);
JsonUtil::AddMember(json, "_lastAccessTimestamp", block.lastAccessTimestamp, allocator);
JsonUtil::AddMember(json, "maxAccessInterval", block.maxAccessInterval, allocator);
JsonUtil::AddMember(json, "lazyUsed", block.lazyUsed, allocator);
JsonUtil::AddMember(json, "delayedFree", block.delayedFree, allocator);
JsonUtil::AddMember(json, "longIdle", block.longIdle, allocator);
return json;
}
struct MemScopeMemoryBlocksResponse : public JsonResponse {
MemScopeMemoryBlocksResponse() : JsonResponse(REQ_RES_MEM_SCOPE_MEMORY_BLOCKS) {}
std::vector<MemoryBlock> blocks;
uint64_t minTimestamp{};
uint64_t maxTimestamp{};
uint64_t minSize{};
uint64_t maxSize{};
uint64_t total{};
[[nodiscard]] std::optional<document_t> ToJson() const override {
document_t json(kObjectType);
auto &allocator = json.GetAllocator();
ProtocolUtil::SetResponseJsonBaseInfo(*this, json);
json_t body(kObjectType);
json_t jsonBlocks(kArrayType);
JsonUtil::AddMember(body, "minTimestamp", minTimestamp, allocator);
JsonUtil::AddMember(body, "maxTimestamp", maxTimestamp, allocator);
JsonUtil::AddMember(body, "minSize", minSize, allocator);
JsonUtil::AddMember(body, "maxSize", maxSize, allocator);
JsonUtil::AddMember(body, "total", total, allocator);
json_t jsonHeaders(kArrayType);
for (const auto &header : BLOCK_TABLE::FIELD_FULL_COLUMNS) {
if (header.visible) {
jsonHeaders.PushBack(header.ToTableHeaderJson(allocator), allocator);
}
}
for (const auto &block : blocks) {
auto blockJson = ToMemScopeMemoryBlockJson(block, allocator);
jsonBlocks.PushBack(blockJson, allocator);
}
JsonUtil::AddMember(body, "blocks", jsonBlocks, allocator);
JsonUtil::AddMember(body, "headers", jsonHeaders, allocator);
JsonUtil::AddMember(json, "body", body, allocator);
return std::optional<document_t>{std::move(json)};
}
};
struct MemScopeMemoryAllocationsResponse : public JsonResponse {
MemScopeMemoryAllocationsResponse() : JsonResponse(REQ_RES_MEM_SCOPE_MEMORY_ALLOCATIONS) {}
uint64_t minTimestamp{};
uint64_t maxTimestamp{};
std::vector<MemoryAllocation> allocations;
[[nodiscard]] std::optional<document_t> ToJson() const override {
document_t json(kObjectType);
auto &allocator = json.GetAllocator();
ProtocolUtil::SetResponseJsonBaseInfo(*this, json);
json_t body(kObjectType);
json_t allocationsJson(kArrayType);
JsonUtil::AddMember(body, "minTimestamp", minTimestamp, allocator);
JsonUtil::AddMember(body, "maxTimestamp", maxTimestamp, allocator);
for (const auto &allocation : allocations) {
auto allocationJson = ToMemScopeMemoryAllocationJson(allocation, allocator);
if (allocationJson.has_value()) {
allocationsJson.PushBack(allocationJson.value(), allocator);
}
}
JsonUtil::AddMember(body, "allocations", allocationsJson, allocator);
JsonUtil::AddMember(json, "body", body, allocator);
return std::optional<document_t>{std::move(json)};
}
static std::optional<document_t> ToMemScopeMemoryAllocationJson(
const MemoryAllocation &allocation, Document::AllocatorType &allocator) {
document_t json(kObjectType);
JsonUtil::AddMember(json, "id", allocation.id, allocator);
JsonUtil::AddMember(json, "timestamp", allocation.timestamp, allocator);
JsonUtil::AddMember(json, "totalSize", allocation.totalSize, allocator);
return std::optional<document_t>{std::move(json)};
}
};
struct MemScopeMemoryDetailsResponse : public JsonResponse {
MemScopeMemoryDetailsResponse() : JsonResponse(REQ_RES_MEM_SCOPE_MEMORY_DETAILS) {}
uint64_t timestamp{};
std::unique_ptr<MemScopeMemoryDetailTreeNode> detail;
[[nodiscard]] std::optional<document_t> ToJson() const override {
document_t json(kObjectType);
auto &allocator = json.GetAllocator();
ProtocolUtil::SetResponseJsonBaseInfo(*this, json);
auto body_json = ToMemScopeDetailTreeJson(detail.get(), allocator);
if (!body_json.has_value()) {
body_json = document_t(kObjectType);
}
JsonUtil::AddMember(json, "body", body_json.value(), allocator);
return std::optional<document_t>{std::move(json)};
}
static std::optional<document_t> ToMemScopeDetailTreeJson(
MemScopeMemoryDetailTreeNode *treeNode, Document::AllocatorType &allocator) {
if (treeNode == nullptr) {
return std::nullopt;
}
document_t json(kObjectType);
JsonUtil::AddMember(json, "name", treeNode->name, allocator);
JsonUtil::AddMember(json, "tag", treeNode->tag, allocator);
JsonUtil::AddMember(json, "size", treeNode->size, allocator);
json_t subNodes(kArrayType);
for (auto &subNode : treeNode->children) {
auto subNodeJson = ToMemScopeDetailTreeJson(subNode.get(), allocator);
if (subNodeJson.has_value()) {
subNodes.PushBack(subNodeJson.value(), allocator);
}
}
JsonUtil::AddMember(json, "subNodes", subNodes, allocator);
return std::optional<document_t>{std::move(json)};
}
};
struct MemScopePythonTracesResponse : public JsonResponse {
MemScopePythonTracesResponse() : JsonResponse(REQ_RES_MEM_SCOPE_PYTHON_TRACES) {}
MemScopePythonTrace trace;
[[nodiscard]] std::optional<document_t> ToJson() const override {
document_t json(kObjectType);
auto &allocator = json.GetAllocator();
ProtocolUtil::SetResponseJsonBaseInfo(*this, json);
document_t body(kObjectType);
auto tracesJson = ToMemScopePythonTracesJson(trace.slices, allocator);
if (!tracesJson.has_value()) {
tracesJson = document_t(kObjectType);
}
JsonUtil::AddMember(body, "traces", tracesJson.value(), allocator);
JsonUtil::AddMember(body, "minTimestamp", trace.minTimestamp, allocator);
JsonUtil::AddMember(body, "maxTimestamp", trace.maxTimestamp, allocator);
JsonUtil::AddMember(body, "maxDepth", trace.maxDepth, allocator);
JsonUtil::AddMember(json, "threadId", trace.threadId, allocator);
JsonUtil::AddMember(json, "body", body, allocator);
return std::optional<document_t>{std::move(json)};
}
static std::optional<document_t> ToMemScopePythonTracesJson(
const std::vector<PythonTraceSlice> &slices, Document::AllocatorType &allocator) {
document_t json(kArrayType);
for (auto &slice : slices) {
document_t traceJson(kObjectType);
JsonUtil::AddMember(traceJson, "func", slice.func, allocator);
JsonUtil::AddMember(traceJson, "startTimestamp", slice.startTimestamp, allocator);
JsonUtil::AddMember(traceJson, "endTimestamp", slice.endTimestamp, allocator);
JsonUtil::AddMember(traceJson, "depth", slice.depth, allocator);
json.PushBack(traceJson, allocator);
}
return std::optional<document_t>{std::move(json)};
}
};
struct MemScopeEventResponse : public JsonResponse {
MemScopeEventResponse() : JsonResponse(REQ_RES_MEM_SCOPE_EVENTS) {}
int64_t total{};
std::vector<MemScopeEvent> events;
bool withCallStackC = false;
bool withCallStackPython = false;
[[nodiscard]] std::optional<document_t> ToJson() const override {
document_t json(kObjectType);
auto &allocator = json.GetAllocator();
ProtocolUtil::SetResponseJsonBaseInfo(*this, json);
json_t body(kObjectType);
json_t headers(kArrayType);
for (auto const &header : EVENT_TABLE::FIELD_FULL_COLUMNS) {
bool needed = true;
if (header.name == EVENT_TABLE::CALL_STACK_C) {
needed = withCallStackC;
}
if (header.name == EVENT_TABLE::CALL_STACK_PYTHON) {
needed = withCallStackPython;
}
if (header.visible && needed) {
headers.PushBack(header.ToTableHeaderJson(allocator), allocator);
}
}
JsonUtil::AddMember(body, "headers", headers, allocator);
JsonUtil::AddMember(body, "events", ToTableDataJson(allocator), allocator);
JsonUtil::AddMember(body, "total", total, allocator);
JsonUtil::AddMember(json, "body", body, allocator);
return std::optional<document_t>{std::move(json)};
}
document_t ToTableDataJson(Document::AllocatorType &allocator) const {
document_t dataJson(kArrayType);
for (auto &event : events) {
document_t eventJson(kObjectType);
JsonUtil::AddMember(eventJson, "id", event.id, allocator);
JsonUtil::AddMember(eventJson, "event", event.event, allocator);
JsonUtil::AddMember(eventJson, "eventType", event.eventType, allocator);
JsonUtil::AddMember(eventJson, "name", event.name, allocator);
JsonUtil::AddMember(eventJson, "_timestamp", event.timestamp, allocator);
JsonUtil::AddMember(eventJson, "processId", event.processId, allocator);
JsonUtil::AddMember(eventJson, "threadId", event.threadId, allocator);
JsonUtil::AddMember(eventJson, "deviceId", event.deviceId, allocator);
JsonUtil::AddMember(eventJson, "ptr", event.ptr, allocator);
JsonUtil::AddMember(eventJson, "attr", event.attr, allocator);
if (withCallStackC) {
JsonUtil::AddMember(eventJson, "callStackC", event.callStackC, allocator);
}
if (withCallStackPython) {
JsonUtil::AddMember(eventJson, "callStackPython", event.callStackPython, allocator);
}
dataJson.PushBack(eventJson, allocator);
}
return dataJson;
}
};
}
#endif