Files
Just-DataInspector/Utilities/Inc/CsvTable.hpp
T
DeepSeek V4.1 Flash 350538c634 命名审查与垃圾代码清理(纯重命名 / 死代码删除,无行为变更)
前提:加载完成后全部采样都已驻留内存,程序此后与源文件再无联系。
据此修正了一批会让人误以为"仍在读写文件"的命名:

- SampleFileAt → SampleSignalAt(取的是内存信号在给定时刻的采样值)。
- DataSet::AddPreparedFile → AddDataFile。
- PlotView::InvalidatePolylineCache → InvalidateDerivedCaches
  (它同时清空折线、边沿统计、中心平均值曲线、静态场景缓存与悬停引用)。
- PlotView::CursorColor(int which) → CursorColor()(两条光标同色,参数从未使用)。
- UiEllipsize(g,…) → UiEllipsize(…):纯测量不绘制,删掉被忽略的绘图上下文参数;
  同时删除与 UiMeasureTextWidth 完全重复的 UiTextWidth,调用点统一到 UiMeasureTextWidth。

清理残留参数((void)xxx;):
- TabConfig 的可见性/网格族(SetVisible / ToggleVisible / SetFileVisible / SetAllVisible /
  SoloSignal / SetMode / SyncLanes / FileHasVisible / FileAllVisible)去掉从未使用的
  const DataSet& 参数(仅 SyncToDataSet 真正需要数据层,保留)。
- PlotView::OnLButtonUp(int y)、OnMouseWheel(int delta, bool shift);PainterSignalHalo 去掉未用的 ref。
- BuildDataFile 中未使用的局部 rowCount。

删除无人调用的死函数:
  DataSet::Clear / AddFromTable;SignalColorCount;WideToUtf8 / StartsWith;
  PlotView::ViewMinTime / ViewMaxTime / EdgePanelRect / EdgePanelCloseRect /
  EdgeCenterPanelRect / ScaleLaneRange / BeginLaneValueEdit / LaneContentHeight;
  SignalPanel::NeedsScrollBar / IsFilterEditing / FilterText / ContentHeight;
  PopupMenu::EditingItemId;TabBar::IsDragging;TextEdit::PlaceCaret。

删除只写不读的死字段:CsvTable::sourceRowCount(与 rowCount 等义)与 skippedRowCount。

以 VERY_BIG_DATA.CSV 回归验证:加载与勾选、筛选框(含"无匹配的筛选信号")、
样式区线宽文案省略、选区放大(横向与纵向)、双光标读数与 Δt、右键菜单(Y 轴数值与
实验性功能子菜单)、合并/拆分网格、标签与信号重命名省略号,行为均与改动前一致;
make clean && make all 无任何警告。
2026-10-09 21:52:46 +08:00

64 lines
2.3 KiB
C++

#ifndef __CSV_TABLE_HPP__
#define __CSV_TABLE_HPP__
#include <cstddef>
#include <functional>
#include <string>
#include <vector>
namespace jdi
{
/**
* @brief CSV 文件的解析结果,保存列名与**列优先**的数值矩阵。
*
* 采用列优先(每条信号一整块连续内存)而不是行优先的二维数组,原因有二:
* 1. 大型文件(百万行级)若按行存储会产生上百万次独立堆分配,
* 每行还要额外承担 vector 的控制块与容量对齐开销,实测内存放大接近 1.5 倍;
* 2. 后续构建信号时可以直接把整列**移动**进 SignalData,不再逐元素拷贝。
*/
struct CsvTable
{
std::vector<std::wstring> headers; /**< 列名(已去除引号与首尾空白)。 */
std::vector<std::vector<double>> columns; /**< 列优先数值矩阵:columns[列][行],缺失处为 NaN。 */
std::size_t rowCount = 0; /**< 有效数据行数。 */
wchar_t delimiter = L','; /**< 实际使用的分隔符。 */
unsigned long long fileBytes = 0; /**< 源文件字节数(用于按比例预留容量)。 */
/**
* @brief 判断解析结果是否包含可用的表格数据。
* @return 存在列名且存在数据行时返回 true。
*/
bool HasData() const
{
return !headers.empty() && (rowCount > 0);
}
};
/**
* @brief 解析进度回调。
*
* 在解析过程中按块回调,ratio 为 0.0-1.0 的完成比例;
* 返回 false 表示请求取消,解析会尽快停止并返回失败。
*/
using CsvProgress = std::function<bool(double ratio)>;
/**
* @brief 读取并解析一个 CSV 文件。
*
* 文件以分块流式方式读取(不把整个文件一次性读入内存),
* 因此内存占用只与解析结果相关,不会因文件体积成倍放大,也没有体积上限。
*
* @param [IN] filePath CSV 文件完整路径(宽字符,支持中文路径)。
* @param [OUT] table 解析结果输出。
* @param [OUT] error 失败原因描述(成功时清空)。
* @param [IN] progress 解析进度回调,可为空。
* @return 解析成功返回 true,否则返回 false。
*/
bool LoadCsvTable(const std::wstring& filePath, CsvTable& table, std::wstring& error,
const CsvProgress& progress = CsvProgress());
} // namespace jdi
#endif // __CSV_TABLE_HPP__