2026-04-25 19:01:54 +08:00
|
|
|
#ifndef DEBUG_DATA_SAVER_H
|
|
|
|
|
#define DEBUG_DATA_SAVER_H
|
|
|
|
|
|
2026-07-03 14:11:39 +08:00
|
|
|
#include <atomic>
|
|
|
|
|
#include <condition_variable>
|
2026-05-25 00:28:08 +08:00
|
|
|
#include <cstdint>
|
2026-07-03 14:11:39 +08:00
|
|
|
#include <map>
|
2026-04-25 19:01:54 +08:00
|
|
|
#include <mutex>
|
|
|
|
|
#include <queue>
|
2026-07-03 14:11:39 +08:00
|
|
|
#include <string>
|
|
|
|
|
#include <thread>
|
|
|
|
|
#include <utility>
|
|
|
|
|
#include <vector>
|
|
|
|
|
|
2026-04-25 19:01:54 +08:00
|
|
|
#include "VZNL_Types.h"
|
|
|
|
|
|
|
|
|
|
class DebugDataSaver
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
explicit DebugDataSaver(int maxThreads = 4);
|
|
|
|
|
~DebugDataSaver();
|
|
|
|
|
|
|
|
|
|
void SaveAsync(const std::string& basePath,
|
|
|
|
|
const std::string& timestamp,
|
|
|
|
|
const std::vector<std::pair<EVzResultDataType, SVzLaserLineData>>& data,
|
|
|
|
|
const std::string& deviceName = "");
|
|
|
|
|
|
|
|
|
|
void Stop();
|
|
|
|
|
|
2026-05-25 00:28:08 +08:00
|
|
|
void SetMaxStorageSize(int64_t bytes) { m_maxStorageSize = bytes; }
|
2026-07-03 14:11:39 +08:00
|
|
|
void SetMaxQueueSize(int maxTasks);
|
|
|
|
|
void PrepareStorageCache(const std::string& basePath);
|
2026-05-25 00:28:08 +08:00
|
|
|
|
2026-04-25 19:01:54 +08:00
|
|
|
private:
|
|
|
|
|
struct SaveTask {
|
2026-07-03 14:11:39 +08:00
|
|
|
std::string basePath;
|
2026-04-25 19:01:54 +08:00
|
|
|
std::string filePath;
|
|
|
|
|
std::string deviceName;
|
|
|
|
|
std::vector<std::pair<EVzResultDataType, SVzLaserLineData>> data;
|
|
|
|
|
};
|
|
|
|
|
|
2026-07-03 14:11:39 +08:00
|
|
|
struct StorageFileInfo {
|
|
|
|
|
std::string path;
|
|
|
|
|
int64_t size = 0;
|
|
|
|
|
int64_t lastModifiedMSecs = 0;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct StorageCache {
|
|
|
|
|
bool initialized = false;
|
|
|
|
|
int64_t totalSize = 0;
|
|
|
|
|
std::vector<StorageFileInfo> files;
|
|
|
|
|
};
|
|
|
|
|
|
2026-04-25 19:01:54 +08:00
|
|
|
void WorkerThread();
|
|
|
|
|
|
|
|
|
|
static std::vector<std::pair<EVzResultDataType, SVzLaserLineData>> DeepCopyData(
|
|
|
|
|
const std::vector<std::pair<EVzResultDataType, SVzLaserLineData>>& src);
|
|
|
|
|
static void FreeData(std::vector<std::pair<EVzResultDataType, SVzLaserLineData>>& data);
|
|
|
|
|
|
2026-07-03 14:11:39 +08:00
|
|
|
std::string GenerateSavePath(const std::string& basePath,
|
|
|
|
|
const std::string& timestamp,
|
|
|
|
|
const std::string& deviceName = "");
|
2026-04-25 19:01:54 +08:00
|
|
|
|
2026-05-25 00:28:08 +08:00
|
|
|
void EnsureStorageLimit(const std::string& basePath);
|
2026-07-03 14:11:39 +08:00
|
|
|
void EnsureStorageLimitLocked(const std::string& basePath, StorageCache& cache);
|
|
|
|
|
void BuildStorageCacheLocked(const std::string& basePath, StorageCache& cache);
|
|
|
|
|
void AddFileToCacheLocked(StorageCache& cache, const StorageFileInfo& fileInfo);
|
|
|
|
|
void RecordSavedFile(const std::string& basePath, const std::string& filePath);
|
2026-05-25 00:28:08 +08:00
|
|
|
|
2026-07-03 14:11:39 +08:00
|
|
|
static bool RemoveFileFromCache(StorageCache& cache, const std::string& filePath);
|
|
|
|
|
static bool IsOlderFile(const StorageFileInfo& lhs, const StorageFileInfo& rhs);
|
2026-05-25 00:28:08 +08:00
|
|
|
static int64_t ComputeDirSize(const std::string& rootPath);
|
|
|
|
|
static std::string FindOldestFile(const std::string& rootPath);
|
|
|
|
|
|
2026-04-25 19:01:54 +08:00
|
|
|
int m_maxThreads;
|
|
|
|
|
std::vector<std::thread> m_workers;
|
|
|
|
|
std::queue<SaveTask> m_taskQueue;
|
|
|
|
|
std::mutex m_queueMutex;
|
|
|
|
|
std::condition_variable m_queueCondition;
|
|
|
|
|
std::atomic<bool> m_running;
|
2026-07-03 14:11:39 +08:00
|
|
|
std::atomic<int> m_maxQueueSize{10};
|
2026-05-25 00:28:08 +08:00
|
|
|
|
|
|
|
|
std::mutex m_diskSpaceMutex;
|
2026-07-03 14:11:39 +08:00
|
|
|
std::atomic<int64_t> m_maxStorageSize{10LL * 1024 * 1024 * 1024};
|
|
|
|
|
std::map<std::string, StorageCache> m_storageCaches;
|
2026-04-25 19:01:54 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#endif // DEBUG_DATA_SAVER_H
|