* -------------------------------------------------------------------------
* 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.
* -------------------------------------------------------------------------
*/
#include "pch.h"
#include "TraceTime.h"
#include "DataBaseManager.h"
#include "VirtualMemoryDataBase.h"
namespace Dic {
namespace Module {
namespace Memory {
using namespace Server;
using namespace Dic::Module::Timeline;
std::vector<std::string> VirtualMemoryDataBase::GetStreamLists(std::string deviceId, std::string deviceIdColumnName) {
std::vector<std::string> streams = {};
DataType type = DataBaseManager::Instance().GetDataType(path);
std::string sql = "";
if (type == DataType::TEXT) {
sql += "SELECT stream FROM " + recordTable +
" WHERE deviceId = ? AND stream <> '' "
"Group BY stream ORDER BY timestamp ASC";
} else if (type == DataType::DB) {
FileType fileType = DataBaseManager::Instance().GetFileType(path);
if (fileType == FileType::PYTORCH) {
std::string streamPtrColumnName = "streamPtr";
std::string timeColumnName = "timestamp";
sql += "SELECT " + streamPtrColumnName + " FROM " + TABLE_MEMORY_RECORD + " WHERE " + deviceIdColumnName +
" = ? AND " + streamPtrColumnName +
" <> ''"
" Group BY " +
streamPtrColumnName + " ORDER BY " + timeColumnName + " ASC";
} else {
ServerLog::Error("Memory tab does not support msprof data.");
return streams;
}
}
sqlite3_stmt *stmt = nullptr;
int result = sqlite3_prepare_v2(db, sql.c_str(), -1, &stmt, nullptr);
if (result != SQLITE_OK) {
ServerLog::Error("Get stream lists. Failed to prepare sql. Error: ", sqlite3_errmsg(db));
return streams;
}
int index = bindStartIndex;
sqlite3_bind_text(stmt, index++, deviceId.c_str(), deviceId.length(), nullptr);
while (sqlite3_step(stmt) == SQLITE_ROW) {
int col = resultStartIndex;
streams.emplace_back(sqlite3_column_string(stmt, col++));
}
sqlite3_finalize(stmt);
return streams;
}
bool VirtualMemoryDataBase::ExecuteMemoryType(std::vector<std::string> &graphId, std::string &type) {
if (!Database::CheckTableContainData(TABLE_STATIC_OPERATOR)) {
type = Module::Memory::MEMORY_TYPE_DYNAMIC;
return true;
}
type = Module::Memory::MEMORY_TYPE_STATIC;
std::string sql = StringUtil::FormatString(
"SELECT DISTINCT {} as graphId FROM {};", StaticOpColumn::GRAPH_ID, TABLE_STATIC_OPERATOR);
sqlite3_stmt *stmt = nullptr;
int result = sqlite3_prepare_v2(db, sql.c_str(), -1, &stmt, nullptr);
if (result != SQLITE_OK) {
ServerLog::Error("Query memory type. Failed to prepare sql. Error: ", sqlite3_errmsg(db));
return false;
}
while (sqlite3_step(stmt) == SQLITE_ROW) {
int col = resultStartIndex;
std::string res = sqlite3_column_string(stmt, col++);
graphId.emplace_back(res);
}
sqlite3_finalize(stmt);
return true;
}
bool VirtualMemoryDataBase::ExecuteMemoryResourceType(std::string &type, std::string sql) {
sqlite3_stmt *stmt = nullptr;
int result = sqlite3_prepare_v2(db, sql.c_str(), -1, &stmt, nullptr);
if (result != SQLITE_OK) {
ServerLog::Error("Query memory resource type. Failed to prepare sql. Error: ", sqlite3_errmsg(db));
return false;
}
int64_t totalNum = 0;
while (sqlite3_step(stmt) == SQLITE_ROW) {
totalNum = sqlite3_column_int(stmt, resultStartIndex);
}
type = (totalNum > 0) ? MEMORY_RESOURCE_TYPE_MIND_SPORE : MEMORY_RESOURCE_TYPE_PYTORCH;
sqlite3_finalize(stmt);
return true;
}
bool VirtualMemoryDataBase::ExecuteOperatorSize(
Protocol::MemoryOperatorSizeParams &requestParams, double &min, double &max, std::string sql) {
sqlite3_stmt *stmt = nullptr;
int result = sqlite3_prepare_v2(db, sql.c_str(), -1, &stmt, nullptr);
if (result != SQLITE_OK) {
ServerLog::Error("Query operator size. Failed to prepare sql. Error: ", sqlite3_errmsg(db));
return false;
}
int index = bindStartIndex;
if (Timeline::DataBaseManager::Instance().GetDataType(path) == DataType::TEXT) {
sqlite3_bind_text(stmt, index++, requestParams.deviceId.c_str(), requestParams.deviceId.length(), nullptr);
} else {
int deviceId = StringUtil::StringToInt(requestParams.deviceId);
sqlite3_bind_int64(stmt, index++, deviceId);
}
while (sqlite3_step(stmt) == SQLITE_ROW) {
int col = resultStartIndex;
min = sqlite3_column_double(stmt, col++);
max = sqlite3_column_double(stmt, col++);
}
sqlite3_finalize(stmt);
return true;
}
bool VirtualMemoryDataBase::ExecuteStaticOperatorSize(
Protocol::StaticOperatorSizeParams &requestParams, double &min, double &max, const std::string &sql) {
sqlite3_stmt *stmt = nullptr;
int result = sqlite3_prepare_v2(db, sql.c_str(), -1, &stmt, nullptr);
if (result != SQLITE_OK) {
ServerLog::Error("Query static operator size. Failed to prepare sql. Error: ", sqlite3_errmsg(db));
return false;
}
int index = bindStartIndex;
if (!requestParams.graphId.empty()) {
sqlite3_bind_text(stmt, index++, requestParams.graphId.c_str(), requestParams.graphId.length(), nullptr);
}
while (sqlite3_step(stmt) == SQLITE_ROW) {
int col = resultStartIndex;
min = sqlite3_column_double(stmt, col++);
max = sqlite3_column_double(stmt, col++);
}
sqlite3_finalize(stmt);
return true;
}
bool VirtualMemoryDataBase::ExecuteComponentTotalNum(
Protocol::MemoryComponentParams &requestParams, int64_t &totalNum, std::string &sql) {
sqlite3_stmt *stmt = nullptr;
int result = sqlite3_prepare_v2(db, sql.c_str(), -1, &stmt, nullptr);
if (result != SQLITE_OK) {
ServerLog::Error("Query components total num. Failed to prepare sql. Error: ", sqlite3_errmsg(db));
return false;
}
int index = bindStartIndex;
if (Timeline::DataBaseManager::Instance().GetDataType(path) == DataType::TEXT) {
sqlite3_bind_text(stmt, index++, requestParams.deviceId.c_str(), requestParams.deviceId.length(), nullptr);
} else {
int deviceId = StringUtil::StringToInt(requestParams.deviceId);
sqlite3_bind_int64(stmt, index++, deviceId);
}
while (sqlite3_step(stmt) == SQLITE_ROW) {
totalNum = sqlite3_column_int(stmt, resultStartIndex);
}
sqlite3_finalize(stmt);
return true;
}
bool VirtualMemoryDataBase::ExecuteStaticOperatorListTotalNum(
Protocol::StaticOperatorListParams &requestParams, int64_t &totalNum, std::string sql) {
sqlite3_stmt *stmt = nullptr;
int result = sqlite3_prepare_v2(db, sql.c_str(), -1, &stmt, nullptr);
if (result != SQLITE_OK) {
ServerLog::Error("Query static operators total num. Failed to prepare sql. Error: ", sqlite3_errmsg(db));
return false;
}
int index = bindStartIndex;
std::string searchName = "%" + requestParams.searchName + "%";
sqlite3_bind_text(stmt, index++, searchName.c_str(), searchName.length(), nullptr);
if (!requestParams.graphId.empty()) {
sqlite3_bind_text(stmt, index++, requestParams.graphId.c_str(), requestParams.graphId.length(), nullptr);
}
if (requestParams.minSize != std::numeric_limits<int64_t>::min()) {
sqlite3_bind_int64(stmt, index++, requestParams.minSize);
}
if (requestParams.maxSize != std::numeric_limits<int64_t>::max()) {
sqlite3_bind_int64(stmt, index++, requestParams.maxSize);
}
while (sqlite3_step(stmt) == SQLITE_ROW) {
totalNum = sqlite3_column_int(stmt, resultStartIndex);
}
sqlite3_finalize(stmt);
return true;
}
bool VirtualMemoryDataBase::ExecuteQueryMemoryViewExecuteSql(Protocol::MemoryViewParams &requestParams,
std::vector<Protocol::ComponentDto> &componentDtoVec, std::vector<std::string> &streams, std::string &sql,
std::string deviceIdColumnName) {
sql = GetCurveSql(requestParams, sql);
sqlite3_stmt *stmt = nullptr;
int result = sqlite3_prepare_v2(db, sql.c_str(), -1, &stmt, nullptr);
if (result != SQLITE_OK) {
ServerLog::Error("Query memory view. Failed to prepare sql. Error: ", sqlite3_errmsg(db));
return false;
}
int index = bindStartIndex;
if (Timeline::DataBaseManager::Instance().GetDataType(path) == DataType::TEXT) {
sqlite3_bind_text(stmt, index++, requestParams.deviceId.c_str(), requestParams.deviceId.length(), nullptr);
} else {
int deviceId = StringUtil::StringToInt(requestParams.deviceId);
sqlite3_bind_int64(stmt, index++, deviceId);
}
std::string peakMemory;
bool onlyGe = true;
componentDtoVec.reserve(2000000);
while (sqlite3_step(stmt) == SQLITE_ROW) {
int col = resultStartIndex;
Protocol::ComponentDto componentDto{};
FastGetString(stmt, col++, componentDto.component);
componentDto.timesTamp = sqlite3_column_double(stmt, col++);
componentDto.totalAllocated = sqlite3_column_double(stmt, col++);
componentDto.totalReserved = sqlite3_column_double(stmt, col++);
componentDto.totalActivated = sqlite3_column_double(stmt, col++);
FastGetString(stmt, col++, componentDto.streamId);
if (std::find(streams.begin(), streams.end(), componentDto.streamId) == streams.end()) {
streams.emplace_back(componentDto.streamId);
}
if (onlyGe && componentDto.component != COMPONENT_GE) {
onlyGe = false;
}
componentDtoVec.push_back(std::move(componentDto));
}
streams.erase(
remove_if(streams.begin(), streams.end(), [](const std::string &s) { return s.empty(); }), streams.end());
sqlite3_finalize(stmt);
if (onlyGe) {
isInference = true;
}
return true;
}
std::string VirtualMemoryDataBase::GetCurveSql(const MemoryViewParams &requestParams, std::string &sql) const {
if (requestParams.type == MEMORY_OVERALL_GROUP) {
sql += " AND component != '" + COMPONENT_PTA + "' ";
}
if (requestParams.type == MEMORY_STREAM_GROUP) {
sql += " AND stream <> '' AND component = '" + COMPONENT_PTA_AND_GE + "'";
}
sql += " ORDER BY timestamp ASC";
return sql;
}
bool VirtualMemoryDataBase::ExecuteQueryMemoryViewGetGraph(Protocol::MemoryViewParams &requestParams,
std::vector<Protocol::ComponentDto> &componentDtoVec, std::vector<std::string> &streams,
Protocol::MemoryViewData &operatorBody) {
Protocol::MemoryPeak peak;
if (requestParams.type == Protocol::MEMORY_OVERALL_GROUP) {
GetOverallLines(componentDtoVec, operatorBody.tempData, operatorBody.legends, peak, streams);
operatorBody.title = GetPeakMemory(peak, streams);
} else if (requestParams.type == Protocol::MEMORY_STREAM_GROUP) {
GetStreamLines(componentDtoVec, operatorBody.tempData, operatorBody.legends, peak, streams);
} else {
GetComponentLines(componentDtoVec, operatorBody.tempData, operatorBody.legends, peak, streams);
operatorBody.title = GetPeakMemory(peak, streams);
}
return true;
}
int64_t VirtualMemoryDataBase::ExecuteOperatorDetail(
Protocol::MemoryOperatorParams &requestParams, std::vector<Protocol::MemoryOperator> &opDetails, std::string &sql) {
int64_t pageSize = requestParams.pageSize <= 0 ? defaultPageSize : requestParams.pageSize;
int64_t currentPage = requestParams.currentPage - 1;
currentPage = currentPage < 0 ? 0 : currentPage;
if (pageSize > maxPageSize || currentPage > maxCurrentPage) {
ServerLog::Error("Error param: pageSize or currentPage");
return -1;
}
int64_t offset = currentPage * pageSize;
sqlite3_stmt *stmt = nullptr;
int result = sqlite3_prepare_v2(db, sql.c_str(), -1, &stmt, nullptr);
if (result != SQLITE_OK) {
ServerLog::Error("Query operator detail. Failed to prepare sql. Error: ", sqlite3_errmsg(db));
return -1;
}
int index = bindStartIndex;
if (Timeline::DataBaseManager::Instance().GetDataType(path) == DataType::TEXT) {
sqlite3_bind_text(stmt, index++, requestParams.deviceId.c_str(), requestParams.deviceId.length(), nullptr);
} else {
int deviceId = StringUtil::StringToInt(requestParams.deviceId);
sqlite3_bind_int64(stmt, index++, deviceId);
}
SqlBindQueryFilters(stmt, index, requestParams);
SqlBindQueryRangeFilters(stmt, index, requestParams);
sqlite3_bind_int64(stmt, index++, pageSize);
sqlite3_bind_int64(stmt, index++, offset);
return QueryOperatorDetailByStepWithCount(stmt, opDetails);
}
int64_t VirtualMemoryDataBase::QueryOperatorDetailByStepWithCount(
sqlite3_stmt *stmt, std::vector<Protocol::MemoryOperator> &operators) {
int64_t count = 0;
while (sqlite3_step(stmt) == SQLITE_ROW) {
int col = resultStartIndex;
count = sqlite3_column_int64(stmt, col++);
Protocol::MemoryOperator operatorDto{};
operatorDto.id = std::to_string(sqlite3_column_int64(stmt, col++));
operatorDto.name = sqlite3_column_string(stmt, col++);
operatorDto.size = sqlite3_column_double(stmt, col++);
operatorDto.allocationTime = ConvertTimestampStr(sqlite3_column_string(stmt, col++));
operatorDto.releaseTime = ConvertTimestampStr(sqlite3_column_string(stmt, col++));
operatorDto.activeReleaseTime = ConvertTimestampStr(sqlite3_column_string(stmt, col++));
operatorDto.duration = sqlite3_column_double(stmt, col++);
operatorDto.activeDuration = sqlite3_column_double(stmt, col++);
operatorDto.allocationAllocated = sqlite3_column_double(stmt, col++);
operatorDto.allocationReserved = sqlite3_column_double(stmt, col++);
operatorDto.allocationActive = sqlite3_column_double(stmt, col++);
operatorDto.releaseAllocated = sqlite3_column_double(stmt, col++);
operatorDto.releaseReserved = sqlite3_column_double(stmt, col++);
operatorDto.releaseActive = sqlite3_column_double(stmt, col++);
operatorDto.streamId = sqlite3_column_string(stmt, col++);
operators.emplace_back(operatorDto);
}
sqlite3_finalize(stmt);
return count;
}
bool VirtualMemoryDataBase::ExecuteQueryEntireOperatorTable(Protocol::MemoryOperatorParams &requestParams,
std::vector<Protocol::MemoryOperator> &opDetails, const std::string &sql) {
sqlite3_stmt *stmt = nullptr;
int result = sqlite3_prepare_v2(db, sql.c_str(), -1, &stmt, nullptr);
if (result != SQLITE_OK) {
ServerLog::Error("Query entire operator table. Failed to prepare sql. Error: ", sqlite3_errmsg(db));
return false;
}
int index = bindStartIndex;
if (Timeline::DataBaseManager::Instance().GetDataType(path) == DataType::TEXT) {
sqlite3_bind_text(stmt, index++, requestParams.deviceId.c_str(), requestParams.deviceId.length(), nullptr);
} else {
int deviceId = StringUtil::StringToInt(requestParams.deviceId);
sqlite3_bind_int64(stmt, index++, deviceId);
}
std::vector<Protocol::MemoryOperator> &operatorDtoVec = opDetails;
while (sqlite3_step(stmt) == SQLITE_ROW) {
int col = resultStartIndex;
Protocol::MemoryOperator operatorDto{};
sqlite3_column_int64(stmt, col++);
operatorDto.id = std::to_string(sqlite3_column_int64(stmt, col++));
operatorDto.name = sqlite3_column_string(stmt, col++);
operatorDto.size = sqlite3_column_double(stmt, col++);
operatorDto.allocationTime = ConvertTimestampStr(sqlite3_column_string(stmt, col++));
operatorDto.releaseTime = ConvertTimestampStr(sqlite3_column_string(stmt, col++));
operatorDto.activeReleaseTime = ConvertTimestampStr(sqlite3_column_string(stmt, col++));
operatorDto.duration = sqlite3_column_double(stmt, col++);
operatorDto.activeDuration = sqlite3_column_double(stmt, col++);
operatorDto.allocationAllocated = sqlite3_column_double(stmt, col++);
operatorDto.allocationReserved = sqlite3_column_double(stmt, col++);
operatorDto.allocationActive = sqlite3_column_double(stmt, col++);
operatorDto.releaseAllocated = sqlite3_column_double(stmt, col++);
operatorDto.releaseReserved = sqlite3_column_double(stmt, col++);
operatorDto.releaseActive = sqlite3_column_double(stmt, col++);
operatorDto.streamId = sqlite3_column_string(stmt, col++);
operatorDtoVec.emplace_back(operatorDto);
}
sqlite3_finalize(stmt);
return true;
}
bool VirtualMemoryDataBase::ExecuteComponentDetail(Protocol::MemoryComponentParams &requestParams,
std::vector<Protocol::MemoryTableColumnAttr> &columnAttr, std::vector<Protocol::MemoryComponent> &componentDetails,
std::string &sql) {
int64_t pageSize = requestParams.pageSize == 0 ? defaultPageSize : requestParams.pageSize;
int64_t currentPage = requestParams.currentPage - 1;
currentPage = currentPage < 0 ? 0 : currentPage;
if (pageSize > maxPageSize || currentPage > maxCurrentPage) {
ServerLog::Error("Error param: pageSize or currentPage");
return false;
}
int64_t offset = currentPage * pageSize;
sqlite3_stmt *stmt = nullptr;
int result = sqlite3_prepare_v2(db, sql.c_str(), -1, &stmt, nullptr);
if (result != SQLITE_OK) {
ServerLog::Error("Query component detail. Failed to prepare sql. Error: ", sqlite3_errmsg(db));
return false;
}
int index = bindStartIndex;
if (Timeline::DataBaseManager::Instance().GetDataType(path) == DataType::TEXT) {
sqlite3_bind_text(stmt, index++, requestParams.deviceId.c_str(), requestParams.deviceId.length(), nullptr);
} else {
sqlite3_bind_int64(stmt, index++, StringUtil::StringToInt(requestParams.deviceId));
}
sqlite3_bind_int64(stmt, index++, requestParams.pageSize);
sqlite3_bind_int64(stmt, index++, offset);
while (sqlite3_step(stmt) == SQLITE_ROW) {
int col = resultStartIndex;
Protocol::MemoryComponent componentElement;
componentElement.component = sqlite3_column_string(stmt, col++);
componentElement.totalReserved = sqlite3_column_double(stmt, col++);
componentElement.timestamp = sqlite3_column_string(stmt, col++);
componentDetails.emplace_back(componentElement);
}
sqlite3_finalize(stmt);
for (const auto &column : componentTableColumnAttr) {
columnAttr.emplace_back(column);
}
return true;
}
bool VirtualMemoryDataBase::ExecuteQueryEntireComponentTable(Protocol::MemoryComponentParams &requestParams,
std::vector<Protocol::MemoryComponent> &componentDetails, std::string &sql) {
sqlite3_stmt *stmt = nullptr;
int result = sqlite3_prepare_v2(db, sql.c_str(), -1, &stmt, nullptr);
if (result != SQLITE_OK) {
ServerLog::Error("Query entire component table. Failed to prepare sql. Error: ", sqlite3_errmsg(db));
return false;
}
int index = bindStartIndex;
if (Timeline::DataBaseManager::Instance().GetDataType(path) == DataType::TEXT) {
sqlite3_bind_text(stmt, index++, requestParams.deviceId.c_str(), requestParams.deviceId.length(), nullptr);
} else {
int deviceId = StringUtil::StringToInt(requestParams.deviceId);
sqlite3_bind_int64(stmt, index++, deviceId);
}
while (sqlite3_step(stmt) == SQLITE_ROW) {
int col = resultStartIndex;
Protocol::MemoryComponent componentElement;
componentElement.component = sqlite3_column_string(stmt, col++);
componentElement.totalReserved = sqlite3_column_double(stmt, col++);
componentElement.timestamp = sqlite3_column_string(stmt, col++);
componentDetails.emplace_back(componentElement);
}
sqlite3_finalize(stmt);
return true;
}
bool VirtualMemoryDataBase::ExecuteStaticGraphTotalSize(
Protocol::StaticOperatorGraphParams &requestParams, const std::string &totalSql, double &totalSize) {
sqlite3_stmt *totalStmt = nullptr;
int totalResult = sqlite3_prepare_v2(db, totalSql.c_str(), -1, &totalStmt, nullptr);
if (totalResult != SQLITE_OK) {
ServerLog::Error("Query static graph total size. Failed to prepare sql. Error: ", sqlite3_errmsg(db));
return false;
}
int index = bindStartIndex;
sqlite3_bind_text(totalStmt, index++, requestParams.graphId.c_str(), requestParams.graphId.length(), nullptr);
if (!requestParams.modelName.empty()) {
std::string modelName = "%" + requestParams.modelName + "%";
sqlite3_bind_text(totalStmt, index++, modelName.c_str(), modelName.length(), nullptr);
}
if (sqlite3_step(totalStmt) == SQLITE_ROW) {
totalSize = sqlite3_column_double(totalStmt, resultStartIndex);
}
sqlite3_finalize(totalStmt);
return true;
}
bool VirtualMemoryDataBase::ExecuteStaticGraphStartIndex(Protocol::StaticOperatorGraphParams &requestParams,
const std::string &graphStartSql, std::map<int64_t, double> &graphSizeMap, int64_t &maxIndex) {
sqlite3_stmt *startStmt = nullptr;
int graphStartResult = sqlite3_prepare_v2(db, graphStartSql.c_str(), -1, &startStmt, nullptr);
if (graphStartResult != SQLITE_OK) {
ServerLog::Error("Query static graph start index. Failed to prepare sql. Error:", sqlite3_errmsg(db));
return false;
}
int index = bindStartIndex;
sqlite3_bind_text(startStmt, index++, requestParams.graphId.c_str(), requestParams.graphId.length(), nullptr);
if (!requestParams.modelName.empty()) {
std::string modelName = "%" + requestParams.modelName + "%";
sqlite3_bind_text(startStmt, index, modelName.c_str(), modelName.length(), nullptr);
}
while (sqlite3_step(startStmt) == SQLITE_ROW) {
int col = resultStartIndex;
int64_t nodeIndex = sqlite3_column_int64(startStmt, col++);
double size = sqlite3_column_double(startStmt, col++);
if (graphSizeMap.find(nodeIndex) != graphSizeMap.end()) {
graphSizeMap[nodeIndex] += size;
} else {
graphSizeMap.insert({nodeIndex, size});
}
if (nodeIndex >= maxUnsignedInt) {
maxIndex = maxUnsignedInt;
} else if (nodeIndex > maxIndex) {
maxIndex = nodeIndex;
}
}
sqlite3_finalize(startStmt);
return true;
}
bool VirtualMemoryDataBase::ExecuteStaticGraphEndIndex(Protocol::StaticOperatorGraphParams &requestParams,
const std::string &graphEndSql, std::map<int64_t, double> &graphSizeMap, int64_t &maxIndex) {
sqlite3_stmt *endStmt = nullptr;
int graphEndResult = sqlite3_prepare_v2(db, graphEndSql.c_str(), -1, &endStmt, nullptr);
if (graphEndResult != SQLITE_OK) {
ServerLog::Error("Query static graph end index. Failed to prepare sql. Error: ", sqlite3_errmsg(db));
return false;
}
int index = bindStartIndex;
sqlite3_bind_text(endStmt, index++, requestParams.graphId.c_str(), requestParams.graphId.length(), nullptr);
if (!requestParams.modelName.empty()) {
std::string modelName = "%" + requestParams.modelName + "%";
sqlite3_bind_text(endStmt, index, modelName.c_str(), modelName.length(), nullptr);
}
while (sqlite3_step(endStmt) == SQLITE_ROW) {
int col = resultStartIndex;
int64_t nodeIndex = sqlite3_column_int64(endStmt, col++);
double size = sqlite3_column_double(endStmt, col++);
if (nodeIndex >= maxUnsignedInt) {
maxIndex = maxUnsignedInt;
} else if (nodeIndex > maxIndex) {
maxIndex = nodeIndex;
}
if (graphSizeMap.find(nodeIndex) != graphSizeMap.end()) {
graphSizeMap[nodeIndex] -= size;
} else {
graphSizeMap.insert({nodeIndex, -size});
}
}
sqlite3_finalize(endStmt);
return true;
}
bool VirtualMemoryDataBase::ExecuteStaticOperatorGraph(Protocol::StaticOperatorGraphParams &requestParams,
Protocol::StaticOperatorGraphItem &graphItem, const std::string &totalSql, const std::string &graphStartSql,
const std::string &graphEndSql) {
double totalSize = staticDefaultTotalSize;
if (!ExecuteStaticGraphTotalSize(requestParams, totalSql, totalSize)) {
return false;
}
if (NumberUtil::IsDoubleEqual(totalSize, staticDefaultTotalSize)) {
ServerLog::Error("Query static operator graph. Failed get TOTAL number. Error: ", sqlite3_errmsg(db));
return false;
}
std::map<int64_t, double> graphSizeMap;
int64_t maxIndex = 0;
if (!ExecuteStaticGraphStartIndex(requestParams, graphStartSql, graphSizeMap, maxIndex)) {
return false;
}
if (!ExecuteStaticGraphEndIndex(requestParams, graphEndSql, graphSizeMap, maxIndex)) {
return false;
}
if (graphSizeMap.empty()) {
ServerLog::Info("Query static operator graph. No data.");
return false;
}
graphItem.legends.insert(graphItem.legends.end(), staticGraphLegends.begin(), staticGraphLegends.end());
double size = 0;
std::string totalSizeStr =
StringUtil::DoubleToStringWithTwoDecimalPlaces(totalSize / kbSizeDouble);
for (auto it = graphSizeMap.begin(); it != graphSizeMap.end(); ++it) {
std::vector<std::string> points = {};
size += it->second;
if (it->first < maxUnsignedInt) {
points.emplace_back(std::to_string(it->first));
} else {
points.emplace_back(std::to_string(maxIndex + 1));
}
points.emplace_back(
StringUtil::DoubleToStringWithTwoDecimalPlaces(size / kbSizeDouble));
points.emplace_back(totalSizeStr);
graphItem.lines.emplace_back(points);
}
return true;
}
int64_t VirtualMemoryDataBase::ExecuteStaticOperatorDetail(Protocol::StaticOperatorListParams &requestParams,
std::vector<Protocol::StaticOperatorItem> &opDetails, const std::string &sql) {
int64_t pageSize = requestParams.pageSize;
if (pageSize == 0) {
pageSize = defaultPageSize;
}
int64_t currentPage = requestParams.currentPage - 1;
if (currentPage < 0) {
currentPage = 0;
}
int64_t offset = currentPage * pageSize;
sqlite3_stmt *stmt = nullptr;
int result = sqlite3_prepare_v2(db, sql.c_str(), -1, &stmt, nullptr);
if (result != SQLITE_OK) {
ServerLog::Error("Query static operator detail. Failed to prepare sql. Error: ", sqlite3_errmsg(db));
return -1;
}
int index = bindStartIndex;
std::string searchName = "%" + requestParams.searchName + "%";
sqlite3_bind_text(stmt, index++, searchName.c_str(), searchName.length(), nullptr);
if (!requestParams.graphId.empty()) {
sqlite3_bind_text(stmt, index++, requestParams.graphId.c_str(), requestParams.graphId.length(), nullptr);
}
sqlite3_bind_int64(stmt, index++, pageSize);
sqlite3_bind_int64(stmt, index++, offset);
std::vector<Protocol::StaticOperatorItem> operatorDtoVec;
int64_t totalNum = 0;
while (sqlite3_step(stmt) == SQLITE_ROW) {
int col = resultStartIndex;
Protocol::StaticOperatorItem operatorDto{};
totalNum = sqlite3_column_int64(stmt, col++);
operatorDto.deviceId = sqlite3_column_string(stmt, col++);
operatorDto.opName = sqlite3_column_string(stmt, col++);
operatorDto.nodeIndexStart = sqlite3_column_int64(stmt, col++);
operatorDto.nodeIndexEnd = sqlite3_column_int64(stmt, col++);
operatorDto.size = sqlite3_column_double(stmt, col++);
operatorDtoVec.emplace_back(operatorDto);
}
sqlite3_finalize(stmt);
opDetails = operatorDtoVec;
return totalNum;
}
bool VirtualMemoryDataBase::ExecuteQueryEntireStaticOperatorTable(Protocol::StaticOperatorListParams &requestParams,
std::vector<Protocol::StaticOperatorItem> &opDetails, const std::string &sql) {
sqlite3_stmt *stmt = nullptr;
int result = sqlite3_prepare_v2(db, sql.c_str(), -1, &stmt, nullptr);
if (result != SQLITE_OK) {
ServerLog::Error("Query entire static operator table. Failed to prepare sql. Error: ", sqlite3_errmsg(db));
return false;
}
int index = bindStartIndex;
if (!requestParams.graphId.empty()) {
sqlite3_bind_text(stmt, index++, requestParams.graphId.c_str(), requestParams.graphId.length(), nullptr);
}
std::vector<Protocol::StaticOperatorItem> operatorDtoVec;
while (sqlite3_step(stmt) == SQLITE_ROW) {
int col = resultStartIndex;
Protocol::StaticOperatorItem operatorDto{};
operatorDto.deviceId = sqlite3_column_string(stmt, col++);
operatorDto.opName = sqlite3_column_string(stmt, col++);
operatorDto.nodeIndexStart = sqlite3_column_int64(stmt, col++);
operatorDto.nodeIndexEnd = sqlite3_column_int64(stmt, col++);
operatorDto.size = sqlite3_column_double(stmt, col++);
operatorDtoVec.emplace_back(operatorDto);
}
sqlite3_finalize(stmt);
opDetails = operatorDtoVec;
return true;
}
std::string VirtualMemoryDataBase::BuildQueryOperatorMemoryTimeCondition(const MemoryOperatorParams &requestParams) {
std::string timeCondition;
if (requestParams.startTime != -1 && requestParams.endTime != -1) {
std::string startTimeStr = std::to_string(requestParams.startTime);
std::string endTimeStr = std::to_string(requestParams.endTime);
if (requestParams.isOnlyShowAllocatedOrReleasedWithinInterval) {
timeCondition = StringUtil::FormatString(" AND (_{} BETWEEN {} AND {} OR _{} BETWEEN {} AND {}) ",
OpMemoryColumn::ALLOCATION_TIME, startTimeStr, endTimeStr, OpMemoryColumn::RELEASE_TIME, startTimeStr,
endTimeStr);
} else {
timeCondition = StringUtil::FormatString(" AND (({} IS NULL OR {} = 0 OR _{} >= {}) AND _{} <= {}) ",
OpMemoryColumn::RELEASE_TIME, OpMemoryColumn::RELEASE_TIME, OpMemoryColumn::RELEASE_TIME, startTimeStr,
OpMemoryColumn::ALLOCATION_TIME, endTimeStr);
}
}
return timeCondition;
}
std::string VirtualMemoryDataBase::BuildQueryFiltersCondition(const FiltersParam &requestParams) {
std::string filtersCondition;
for (auto &filterPair : requestParams.filters) {
filtersCondition.append(StringUtil::FormatString(" AND _{} LIKE ? ", filterPair.first));
}
return filtersCondition;
}
std::string VirtualMemoryDataBase::BuildQueryRangeFiltersCondition(const RangeFiltersParam &requestParams) {
std::string rangeFiltersCondition;
for (const auto &[colName, rangePair] : requestParams.rangeFilters) {
(void)(rangePair);
rangeFiltersCondition.append(StringUtil::FormatString(" AND (_{} BETWEEN ? AND ?) ", colName));
}
return rangeFiltersCondition;
}
std::string VirtualMemoryDataBase::BuildQueryOrderByCondition(const OrderByParam &orderParam) {
if (orderParam.orderBy.empty()) {
return "";
}
std::string order = orderParam.desc ? "DESC" : "ASC";
if (orderParam.orderBy == OpMemoryColumn::RELEASE_TIME ||
orderParam.orderBy == OpMemoryColumn::ACTIVE_RELEASE_TIME) {
return StringUtil::FormatString(" ORDER BY CASE WHEN {} IS NULL OR {} = 0 THEN 1 ELSE 0 END {}, _{} {} ",
orderParam.orderBy, orderParam.orderBy, order, orderParam.orderBy, order);
}
if (orderParam.orderBy == OpMemoryColumn::ALLOCATION_TIME) {
return StringUtil::FormatString(" ORDER BY CASE WHEN {} IS NULL OR {} = 0 THEN 0 ELSE 1 END {}, _{} {} ",
orderParam.orderBy, orderParam.orderBy, order, orderParam.orderBy, order);
}
return StringUtil::FormatString(" ORDER BY _{} {} ", orderParam.orderBy, order);
}
void VirtualMemoryDataBase::SqlBindQueryFilters(sqlite3_stmt *stmt, int &bindIndex, const FiltersParam ¶ms) {
if (stmt == nullptr) {
ServerLog::Error("Failed to bind query filters param, empty stmt");
return;
}
if (params.filters.size() > INT_MAX || bindIndex > static_cast<int>(INT_MAX - params.filters.size())) {
ServerLog::Error("Failed to bind query filters param, over limit.");
return;
}
for (auto &filterPair : params.filters) {
std::string filterPattern = StringUtil::FormatString("%{}%", filterPair.second);
sqlite3_bind_text(stmt, bindIndex++, filterPattern.c_str(), filterPattern.length(), SQLITE_TRANSIENT);
}
}
void VirtualMemoryDataBase::SqlBindQueryRangeFilters(
sqlite3_stmt *stmt, int &bindIndex, const RangeFiltersParam ¶ms) {
if (stmt == nullptr) {
ServerLog::Error("Failed to bind query range filters param, empty stmt");
return;
}
if (params.rangeFilters.size() > INT_MAX || bindIndex > static_cast<int>(INT_MAX - params.rangeFilters.size())) {
ServerLog::Error("Failed to bind query range filters param, over limit.");
return;
}
for (const auto &[colName, rangePair] : params.rangeFilters) {
(void)(colName);
sqlite3_bind_double(stmt, bindIndex++, rangePair.first);
sqlite3_bind_double(stmt, bindIndex++, rangePair.second);
}
}
void VirtualMemoryDataBase::AddOperatorSql(Protocol::MemoryOperatorParams requestParams, std::string &sql) {
if (requestParams.type == Protocol::MEMORY_STREAM_GROUP) {
sql = StringUtil::StrJoin(sql, StringUtil::FormatString(" AND _{} <> '' ", OpMemoryColumn::STREAM));
}
std::string timeCondition = BuildQueryOperatorMemoryTimeCondition(requestParams);
std::string filtersCondition = BuildQueryFiltersCondition(requestParams);
std::string rangeFiltersCondition = BuildQueryRangeFiltersCondition(requestParams);
std::string orderByCondition = BuildQueryOrderByCondition(requestParams);
sql = StringUtil::StrJoin(
sql, timeCondition, filtersCondition, rangeFiltersCondition, orderByCondition, " LIMIT ? OFFSET ? ");
}
void VirtualMemoryDataBase::AddStableOperatorSql(Protocol::StaticOperatorListParams requestParams, std::string &sql) {
if (!requestParams.graphId.empty()) {
sql += StringUtil::FormatString(" AND {} = ? ", StaticOpColumn::GRAPH_ID);
}
if (requestParams.startNodeIndex >= 0 && requestParams.endNodeIndex >= requestParams.startNodeIndex) {
std::string tmpBetweenAndSql = StringUtil::FormatString("BETWEEN {} AND {}",
std::to_string(requestParams.startNodeIndex), std::to_string(requestParams.endNodeIndex));
sql += StringUtil::FormatString(" AND ({} {} OR {} {}) ", StaticOpColumn::NODE_INDEX_START, tmpBetweenAndSql,
StaticOpColumn::NODE_INDEX_END, tmpBetweenAndSql);
}
if (requestParams.minSize != std::numeric_limits<int64_t>::min()) {
sql += StringUtil::FormatString(" AND {} >= {} ", StaticOpColumn::SIZE, std::to_string(requestParams.minSize));
}
if (requestParams.maxSize != std::numeric_limits<int64_t>::max()) {
sql += StringUtil::FormatString(" AND {} <= {} ", StaticOpColumn::SIZE, std::to_string(requestParams.maxSize));
}
if (!requestParams.orderBy.empty()) {
std::string ascend = requestParams.desc ? "DESC" : "ASC";
sql += StringUtil::FormatString(" ORDER BY {} {} ", requestParams.orderBy, ascend);
}
sql += " LIMIT ? offset ?";
}
void VirtualMemoryDataBase::BuildOverallLinesComponentPoints(const Protocol::ComponentDto &item,
const std::vector<std::string> &streams, Protocol::MemoryPeak &peak, std::vector<double> &lines) {
peak.appReserved = std::max(peak.appReserved, item.totalReserved);
if (peak.hasPtaGe) {
lines.emplace_back(std::numeric_limits<double>::quiet_NaN());
}
if (!streams.empty()) {
lines.emplace_back(std::numeric_limits<double>::quiet_NaN());
}
if (peak.hasPtaGe) {
lines.emplace_back(std::numeric_limits<double>::quiet_NaN());
}
lines.emplace_back(item.totalReserved);
if (peak.hasWorkspace) {
lines.insert(lines.end(), workspaceLegends.size(), std::numeric_limits<double>::quiet_NaN());
}
}
void VirtualMemoryDataBase::BuildOverallLinesFrameworkPoints(const Protocol::ComponentDto &item,
const std::vector<std::string> &streams, Protocol::MemoryPeak &peak, std::vector<double> &lines) {
peak.ptaGeAllocated = std::max(peak.ptaGeAllocated, item.totalAllocated);
peak.ptaGeReserved = std::max(peak.ptaGeReserved, item.totalReserved);
peak.ptaGeActivated = std::max(peak.ptaGeActivated, item.totalActivated);
lines.emplace_back(item.totalAllocated);
if (!streams.empty()) {
lines.emplace_back(item.totalActivated);
}
lines.emplace_back(item.totalReserved);
if (peak.hasApp) {
lines.emplace_back(std::numeric_limits<double>::quiet_NaN());
}
if (peak.hasWorkspace) {
lines.insert(lines.end(), workspaceLegends.size(), std::numeric_limits<double>::quiet_NaN());
}
}
void VirtualMemoryDataBase::BuildOverallLinesWorkspacePoints(const Protocol::ComponentDto &item,
const std::vector<std::string> &streams, Protocol::MemoryPeak &peak, std::vector<double> &lines) {
if (peak.hasPtaGe) {
lines.emplace_back(std::numeric_limits<double>::quiet_NaN());
}
if (!streams.empty()) {
lines.emplace_back(std::numeric_limits<double>::quiet_NaN());
}
if (peak.hasPtaGe) {
lines.emplace_back(std::numeric_limits<double>::quiet_NaN());
}
if (peak.hasApp) {
lines.emplace_back(std::numeric_limits<double>::quiet_NaN());
}
lines.emplace_back(item.totalAllocated);
lines.emplace_back(item.totalReserved);
}
* 将多个单条线的数据组装成[x,y,y,y,y]的格式。
* 各元素分别表示标签"Time (ms)", "Operators Allocated", "Operators Activated", "Operators Reserved" "App Reserved"。
* 如果整组数据中某个标签的数据都不存在,不仅在标签中删除,也在[x,y,y,y,y]中删除该元素。
* 如果只是部分时间上某些标签的数据不存在,则补NULL。
*/
void VirtualMemoryDataBase::GetOverallLines(const componentDtoVector &componentDtoVec, std::vector<double> &lines,
std::vector<std::string> &legends, Protocol::MemoryPeak &peak, const std::vector<std::string> &streams) {
GetOverallLinesLegends(componentDtoVec, legends, peak, streams);
for (auto &item : componentDtoVec) {
if (item.component == COMPONENT_APP) {
lines.emplace_back(item.timesTamp);
BuildOverallLinesComponentPoints(item, streams, peak, lines);
continue;
}
if (item.component == COMPONENT_PTA_AND_GE || item.component == MIND_SPORE_GE ||
(isInference && item.component == COMPONENT_GE)) {
lines.emplace_back(item.timesTamp);
BuildOverallLinesFrameworkPoints(item, streams, peak, lines);
continue;
}
if (item.component == COMPONENT_WORKSPACE) {
lines.emplace_back(item.timesTamp);
BuildOverallLinesWorkspacePoints(item, streams, peak, lines);
}
}
}
void VirtualMemoryDataBase::GetOverallLinesLegends(const componentDtoVector &componentDtoVec,
std::vector<std::string> &legends, Protocol::MemoryPeak &peak, const std::vector<std::string> &streams) {
for (auto &item : componentDtoVec) {
if (item.component == COMPONENT_WORKSPACE) {
peak.hasWorkspace = true;
continue;
}
if (item.component == COMPONENT_PTA_AND_GE || item.component == MIND_SPORE_GE ||
(isInference && item.component == COMPONENT_GE)) {
peak.hasPtaGe = true;
continue;
}
if (item.component == COMPONENT_APP) {
peak.hasApp = true;
}
}
for (const auto &legend : baseLegends) {
if (!peak.hasPtaGe && legend == "Operators Allocated") {
continue;
}
if (streams.empty() && legend == "Operators Activated") {
continue;
}
if (!peak.hasPtaGe && legend == "Operators Reserved") {
continue;
}
legends.emplace_back(legend);
}
if (peak.hasApp) {
legends.emplace_back(appLegend);
}
if (peak.hasWorkspace) {
legends.insert(legends.end(), workspaceLegends.begin(), workspaceLegends.end());
}
}
void VirtualMemoryDataBase::GetComponentLines(const Dic::Module::Memory::componentDtoVector &componentDtoVec,
std::vector<double> &lines, std::vector<std::string> &legends, Protocol::MemoryPeak &peak,
const std::vector<std::string> &streams) {
GetComponentLinesLegends(componentDtoVec, legends, peak);
const int sizeMembers = 3;
for (auto &item : componentDtoVec) {
if (item.component == COMPONENT_PTA) {
peak.ptaAllocated = std::max(peak.ptaAllocated, item.totalAllocated);
peak.ptaReserved = std::max(peak.ptaReserved, item.totalReserved);
peak.ptaActivated = std::max(peak.ptaActivated, item.totalActivated);
lines.emplace_back(item.timesTamp);
InsertSize(lines, item);
if (peak.hasGe) {
InsertStringNull(lines, sizeMembers);
}
if (peak.hasApp) {
InsertStringNull(lines, 1);
}
} else if (item.component == COMPONENT_GE) {
peak.geAllocated = std::max(peak.geAllocated, item.totalAllocated);
peak.geReserved = std::max(peak.geReserved, item.totalReserved);
peak.geActivated = std::max(peak.geActivated, item.totalActivated);
lines.emplace_back(item.timesTamp);
if (peak.hasPta) {
InsertStringNull(lines, sizeMembers);
}
InsertSize(lines, item);
if (peak.hasApp) {
InsertStringNull(lines, 1);
}
} else if (item.component == COMPONENT_APP) {
peak.appReserved = std::max(peak.appReserved, item.totalReserved);
lines.emplace_back(item.timesTamp);
if (peak.hasPta) {
InsertStringNull(lines, sizeMembers);
}
if (peak.hasGe) {
InsertStringNull(lines, sizeMembers);
}
lines.emplace_back(item.totalReserved);
}
}
}
void VirtualMemoryDataBase::InsertSize(std::vector<double> &points, const Protocol::ComponentDto &item) {
points.emplace_back(item.totalAllocated);
points.emplace_back(item.totalActivated);
points.emplace_back(item.totalReserved);
}
void VirtualMemoryDataBase::InsertStringNull(std::vector<double> &points, const int times) {
points.insert(points.end(), times, std::numeric_limits<double>::quiet_NaN());
}
void VirtualMemoryDataBase::GetComponentLinesLegends(const Dic::Module::Memory::componentDtoVector &componentDtoVec,
std::vector<std::string> &legends, Protocol::MemoryPeak &peak) {
for (auto &item : componentDtoVec) {
if (item.component == COMPONENT_PTA) {
peak.hasPta = true;
} else if (item.component == COMPONENT_GE) {
peak.hasGe = true;
} else if (item.component == COMPONENT_APP) {
peak.hasApp = true;
}
}
legends = componentTimeLegends;
if (peak.hasPta) {
legends.insert(legends.end(), componentPtaLegends.begin(), componentPtaLegends.end());
}
if (peak.hasGe) {
legends.insert(legends.end(), componentGeLegends.begin(), componentGeLegends.end());
}
if (peak.hasApp) {
legends.emplace_back(appLegend);
}
}
void VirtualMemoryDataBase::GetStreamLines(const componentDtoVector &componentDtoVec, std::vector<double> &lines,
std::vector<std::string> &legends, Protocol::MemoryPeak &peak, const std::vector<std::string> &streams) {
if (componentDtoVec.empty() && streams.empty()) {
legends.insert(legends.end(), baseLegends.begin(), baseLegends.end());
} else {
legends.emplace_back(baseLegends[0]);
}
for (const auto &stream : streams) {
legends.emplace_back("Allocated of " + stream);
legends.emplace_back("Activated of " + stream);
legends.emplace_back("Reserved of " + stream);
}
for (auto &item : componentDtoVec) {
if (item.component != COMPONENT_PTA_AND_GE) {
continue;
}
lines.emplace_back(item.timesTamp);
std::string streamId = item.streamId;
for (const auto &stream : streams) {
if (stream == streamId) {
lines.emplace_back(item.totalAllocated);
lines.emplace_back(item.totalActivated);
lines.emplace_back(item.totalReserved);
} else {
lines.insert(lines.end(), 3, std::numeric_limits<double>::quiet_NaN());
}
}
}
}
std::string VirtualMemoryDataBase::GetPeakMemory(
const Protocol::MemoryPeak &peak, const std::vector<std::string> &streams) {
std::string peakMemory = "Peak Memory Usage: ";
const size_t decimalPlacesNum = 4;
if (peak.hasPtaGe) {
std::string ptaGeAllo = std::to_string(peak.ptaGeAllocated);
ptaGeAllo = ptaGeAllo.substr(0, ptaGeAllo.length() - decimalPlacesNum);
peakMemory.append("Operator Allocated: ").append(ptaGeAllo).append("MB");
if (!streams.empty()) {
std::string ptaGeActive = std::to_string(peak.ptaGeActivated);
ptaGeActive = ptaGeActive.substr(0, ptaGeActive.length() - decimalPlacesNum);
peakMemory.append(" | Operator Activated: ").append(ptaGeActive).append("MB");
}
std::string ptaGeRe = std::to_string(peak.ptaGeReserved);
ptaGeRe = ptaGeRe.substr(0, ptaGeRe.length() - decimalPlacesNum);
peakMemory.append(" | Operator Reserved: ").append(ptaGeRe).append("MB");
}
if (peak.hasPta) {
std::string ptaAllocatedText = std::to_string(peak.ptaAllocated);
ptaAllocatedText = ptaAllocatedText.substr(0, ptaAllocatedText.length() - decimalPlacesNum);
peakMemory.append("PTA Allocated: ").append(ptaAllocatedText).append("MB");
std::string ptaActi = std::to_string(peak.ptaActivated);
ptaActi = ptaActi.substr(0, ptaActi.length() - decimalPlacesNum);
peakMemory.append(" | PTA Activated: ").append(ptaActi).append("MB");
std::string ptaRes = std::to_string(peak.ptaReserved);
ptaRes = ptaRes.substr(0, ptaRes.length() - decimalPlacesNum);
peakMemory.append(" | PTA Reserved: ").append(ptaRes).append("MB");
}
if (peak.hasGe) {
std::string geAllo = std::to_string(peak.geAllocated);
geAllo = geAllo.substr(0, geAllo.length() - decimalPlacesNum);
peakMemory.append(" | GE Allocated: ").append(geAllo).append("MB");
std::string geActi = std::to_string(peak.geActivated);
geActi = geActi.substr(0, geActi.length() - decimalPlacesNum);
peakMemory.append(" | GE Activated: ").append(geActi).append("MB");
std::string geRes = std::to_string(peak.geReserved);
geRes = geRes.substr(0, geRes.length() - decimalPlacesNum);
peakMemory.append(" | GE Reserved: ").append(geRes).append("MB");
}
if (peak.hasApp) {
std::string appReservedText = std::to_string(peak.appReserved);
appReservedText = appReservedText.substr(0, appReservedText.length() - decimalPlacesNum);
peakMemory.append(" | APP Reserved: ").append(appReservedText).append("MB");
}
return peakMemory;
}
std::string VirtualMemoryDataBase::GetSelectOperatorMemoryFullColumnsWithCount(uint64_t baseTimestamp) {
std::string columns = "COUNT(*) OVER() AS countOver";
for (const auto &columnObj : OperatorMemoryTableView::FIELD_FULL_COLUMNS) {
std::string selectColumn;
std::string alias;
GetSelectOperatorMemoryColumnAndAlias(columnObj.key, baseTimestamp, selectColumn, alias);
std::string select = StringUtil::FormatString(", {} AS {}", selectColumn, alias);
columns.append(select);
}
return columns;
}
std::string VirtualMemoryDataBase::ConvertTimestampStr(const std::string ×tampStr) {
std::string result = timestampStr;
if (timestampStr.empty() || timestampStr[0] == '-') {
result = "N/A";
}
return result;
}
void VirtualMemoryDataBase::GetStaticOperatorColumns(std::vector<Protocol::MemoryTableColumnAttr> ©To) {
for (const auto &col : staticOpTableColumnAttr) {
copyTo.push_back(col);
}
}
}
}
}