diff --git a/plugins/mindstudio-insight-plugins/Histogram/server/src/viewManager/FileMonitor.h b/plugins/mindstudio-insight-plugins/Histogram/server/src/viewManager/FileMonitor.h new file mode 100644 index 0000000000000000000000000000000000000000..081128e4cf4fc3c3c29902bff67d1801327a8934 --- /dev/null +++ b/plugins/mindstudio-insight-plugins/Histogram/server/src/viewManager/FileMonitor.h @@ -0,0 +1,93 @@ +/* +* Copyright (c), Huawei Technologies Co., Ltd. 2024-2024.All rights reserved. +*/ +#ifndef FILEMONITOR_H +#define FILEMONITOR_H +#include +#include +#include +#include +#include +#ifdef _WIN32 +#include +namespace fs = std::filesystem; +#else + +#include + +namespace fs = std::experimental::filesystem; +#endif +#include +#include + +namespace Insight::Histogram { + class FileMonitor { + public: + FileMonitor() : monitoring(false) {} + + void StartMonitoring(const std::string& path) { + directoryPath = path; + monitoring = true; + monitorThread = std::thread(&FileMonitor::MonitorDirectory, this); + } + + void StopMonitoring() { + { + std::lock_guard lock(mtx); + newFiles.clear(); + monitoring = false; + } + cv.notify_one(); + if (monitorThread.joinable()) { + monitorThread.join(); + } + } + + std::vector GetNewFiles() { + std::lock_guard lock(mtx); + std::vector files =newFiles; + newFiles.clear(); + return files; + } + + private: + void MonitorDirectory() { + std::unordered_set existingFiles = GetAllFiles(directoryPath); + while (true) { + std::this_thread::sleep_for(std::chrono::milliseconds(10000)); + std::unordered_set currentFiles = GetAllFiles(directoryPath); + { + std::lock_guard lock(mtx); + if (!monitoring) { + break; + } + for (const auto& file : currentFiles) { + if (existingFiles.find(file) == existingFiles.end()) { + newFiles.push_back(file); + } + } + } + + existingFiles = std::move(currentFiles); + } + } + + std::unordered_set GetAllFiles(const std::string& path) { + std::unordered_set files; + for (const auto& entry : fs::recursive_directory_iterator(path)) { + if (fs::is_regular_file(entry.path())) { + files.insert(entry.path().string()); + } + } + return files; + } + + std::string directoryPath; + std::vector newFiles; + std::thread monitorThread; + std::mutex mtx; + std::condition_variable cv; + bool monitoring; + }; +} +#endif //FILEMONITOR_H diff --git a/plugins/mindstudio-insight-plugins/Histogram/server/src/viewManager/ViewFile.h b/plugins/mindstudio-insight-plugins/Histogram/server/src/viewManager/ViewFile.h new file mode 100644 index 0000000000000000000000000000000000000000..d6d8fd1b5b6c0d9380296e3b37e9d1cd59ec0d94 --- /dev/null +++ b/plugins/mindstudio-insight-plugins/Histogram/server/src/viewManager/ViewFile.h @@ -0,0 +1,33 @@ +/* +* Copyright (c), Huawei Technologies Co., Ltd. 2024-2024.All rights reserved. +*/ +#ifndef VIEW_FILE_GRAPH_H +#define VIEW_FILE_GRAPH_H + +#include +#include +#include + +#include "defs/HistoConceptDefs.h" + +using namespace Insight; +namespace Insight::Histogram { +using namespace Insight::Histogram; + +/* +* 每个要在前端呈现的界面基本内容 +* 包括文件完整路径 +* tag和图的对应关系 +* 以及上一次读取的文件位置 +*/ +class ViewFile { +public: +private: + std::string filePath; + std::streampos lastreadPos; + // 该文件里tag 和 图的对应关系 + std::unordered_map> tagToHistograms; +}; + +} // Histogram +#endif //VIEW_FILE_GRAPH_H diff --git a/plugins/mindstudio-insight-plugins/Histogram/server/src/viewManager/histogramViewGraphs.h b/plugins/mindstudio-insight-plugins/Histogram/server/src/viewManager/histogramViewGraphs.h new file mode 100644 index 0000000000000000000000000000000000000000..90c5a76c3e6c24bc5a453f3e1c77fc7854967d22 --- /dev/null +++ b/plugins/mindstudio-insight-plugins/Histogram/server/src/viewManager/histogramViewGraphs.h @@ -0,0 +1,34 @@ +/* +* Copyright (c), Huawei Technologies Co., Ltd. 2024-2024.All rights reserved. +*/ +#ifndef BOARD_HISTOGRAM_VIEW_GRAPH_H +#define BOARD_HISTOGRAM_VIEW_GRAPH_H + +#include +#include +#include + +#include "defs/HistoConceptDefs.h" + +using namespace Insight; +namespace Insight::Histogram { +using namespace Insight::Histogram; + +/* +* 这个类是关于界面呈现的所有数据的综合存储,包括从文件到tag 以及从tag到每一张图的对应 +* 当文件或者路径有变更时,由 管理类进行更新 +*/ +class HistogramViewGraphs { +public: +private: + void AddFilePathToTag(); + void AddTagToHistogram(); + void Reset(); + + // 在界面上呈现的数据映射关系 文件 - tag - 图,调用parser的时候更新 + std::unordered_map> filePathToTag; + std::unordered_map> tagToHistograms; +}; + +} // Histogram +#endif //BOARD_HISTOGRAM_VIEW_GRAPH_H \ No newline at end of file diff --git a/plugins/mindstudio-insight-plugins/Histogram/server/src/viewManager/histogramViewManager.h b/plugins/mindstudio-insight-plugins/Histogram/server/src/viewManager/histogramViewManager.h new file mode 100644 index 0000000000000000000000000000000000000000..3c63f039c7a71cfa63fe3d9771c49871ef49f0f6 --- /dev/null +++ b/plugins/mindstudio-insight-plugins/Histogram/server/src/viewManager/histogramViewManager.h @@ -0,0 +1,161 @@ +/* +* Copyright (c), Huawei Technologies Co., Ltd. 2024-2024.All rights reserved. +*/ +#ifndef BOARD_HISTOGRAM_VIEW_MANAGER_H +#define BOARD_HISTOGRAM_VIEW_MANAGER_H + +#include +#include +#include +#ifdef _WIN32 +#include +namespace fs = std::filesystem; +#else + +#include + +namespace fs = std::experimental::filesystem; +#endif + +#include "ViewFile.h" +#include "FileMonitor.h" + +namespace Insight::Histogram { +// 在界面上呈现的文件数据 +struct ViewFileInfo { + // 界面上已解析文件的偏移量,主要用来在文件有变更时做追加 + uint64_t offset_{0}; + // 该文件的tag数据 + std::vector tags_; + // 解析之后的直方图数据,tag - HistogramLines的映射形式,有新增则追加 + std::map tagTohistoGraph_; + // 上一次的请求时的tag位置 + int lastTagSize_{0}; + + ViewFileInfo() = default; + ViewFileInfo(uint64_t offset, std::set tags, + std::map tagTohistoGraph) : + offset_(offset), tagTohistoGraph_(tagTohistoGraph) { + tags_.clear(); + tags_.reserve(tags.size()); + std::copy(tags.begin(), tags.end(), std::back_inserter(tags_)); + } + + void Update(uint64_t offset, std::set curentTags, + std::map tagTohistoGraph) { + // 偏移量需要更新 + offset_ = offset; + // 把新增的tag添加在tags_的后面 + for (const auto& tag : curentTags) { + if (std::find(tags_.begin(), tags_.end(), tag) == tags_.end()) { + tags_.push_back(tag); + } + } + // 对获取到的数据更新 + for (auto tagPair : tagTohistoGraph) { + // 没有就重新加一个 + if (tagTohistoGraph_.count(tagPair.first) == 0) { + tagTohistoGraph_[tagPair.first] = tagPair.second; + } else { + tagTohistoGraph_[tagPair.first].MergeData(tagPair.second); + } + } + } + + std::vector GetNewTags() { + // 从上一次索引的下一个开始的,就是最新的数据 + int idx = lastTagSize_; + if (idx < 0 || idx >= tagTohistoGraph_.size()) { + return {}; + } + // 更新索引 + lastTagSize_ = tags_.size(); + return std::vector(tags_.begin() + idx, tags_.end()); + } +}; + +class HistogramViewManager { +public: + // 开启文件监控,监控新增文件以及有变更的文件 + HistogramViewManager(const HistogramViewManager&) = delete; + HistogramViewManager& operator=(const HistogramViewManager&) = delete; + HistogramViewManager(HistogramViewManager &&) = delete; + static HistogramViewManager& getInstance() + { + static HistogramViewManager instance; + return instance; + } + + void SetViewFileList(const std::string &filePath, uint64_t offset, std::set tags, + std::map tagTohistoGraph) + { + ViewFileInfo fileInfo = ViewFileInfo(offset, tags, tagTohistoGraph); + ViewFileList[filePath] = fileInfo; + } + // 根据前端请求返回需要的tag数据 + void AppendNewFileInfo(const std::string &filePath, uint64_t offset, std::set tags, + std::map newGraphs) + { + if (newGraphs.empty()) { + return; + } + // 之前没存储过这个文件,就直接存储进来 + if (ViewFileList.find(filePath) == ViewFileList.end()) { + SetViewFileList(filePath, offset, tags, newGraphs); + return; + } + // 之前有存储过,则需要更新文件信息 + ViewFileList[filePath].Update(offset, tags, newGraphs); + } + + + uint64_t GetReaderOffsetByFilePath(std::string filePath) { + if (ViewFileList.find(filePath) != ViewFileList.end()) { + return ViewFileList[filePath].offset_; + } + return 0; + } + std::map GetHistoInfoByFilePath(std::string filePath) { + std::map info; + if (ViewFileList.find(filePath) != ViewFileList.end()) { + return ViewFileList[filePath].tagTohistoGraph_; + } + return info; + } + + std::vector GetNewTagsByFilePath(const std::string &filePath) { + if (ViewFileList.find(filePath) != ViewFileList.end()) { + return ViewFileList[filePath].GetNewTags(); + } + return {}; + } + // 文件监控相关操作 + void StartFileWatch(const std::string &rootPath) { + // 启动文件监控线程 + fileMonitor.StartMonitoring(rootPath); + } + void StopFileWatch() { + fileMonitor.StopMonitoring(); + } + std::vector GetNewFiles() { + return fileMonitor.GetNewFiles(); + } + + // 需要新增一个清空,当import命令进来的时候这个单例要清空掉,并停止文件监控。重新开始记录 + void Reset() { + ViewFileList.clear(); + StopFileWatch(); + } +private: + // 私有构造函数防止实例化 + HistogramViewManager() {} + ~HistogramViewManager() { + StopFileWatch(); + } + // 已经在界面呈现的文件 文件名-文件信息 + std::unordered_map ViewFileList; + FileMonitor fileMonitor; +}; + +} // Histo +#endif //BOARD_SCALARVISUALLYSERVER_H