eis/eqpalg/eqpalg_changes_2026-05-15.md

238 lines
11 KiB
Markdown
Raw Normal View History

# eqpalg 重构变更文档 — 2026-05-15
## 概述
对 eqpalg 核心架构进行系统性重构,消除历史遗留的补丁设计,将 God Class `ExpBase`1956 行)拆分为 10 个职责清晰的组件和算法子类。
**变更规模**37 文件,+2876 / -1326 行34 个 commit含编译修复
---
## 一、解决的问题
### 1.1 消除双 FunVars 和 is_exp_alg_ 补丁
**根因**ExpModule 是后来引入的表达式模块,用于让非 ExpBase 算法也能使用前置表达式PRR。但 ExpBase 已有自己的表达式管理和 FunVars 实例,两者并存导致:
- 两套 FunVarsExpBase::fun_vars_ 和 ExpModule::fun_vars_
- `is_exp_alg_` 引用传递标志,告诉 ExpModule 在 ExpBase 上下文中"闭嘴"
- 两套几乎相同的变量刷新代码ExpBase::refresh_exp_vars_mem/ihd 和 ExpModule::refresh_exp_vars_mem/ihd_mem
**解决方案**:创建 `ExpressionEngine` 统一表达式引擎,替代 ExpModule + ExpBase 的表达式管理。
### 1.2 消除反馈状态机碎片化
**根因**:反馈动作的状态转换分散在 4 个方法(`act_start_done`、`act_not_hold`、`act_done`、`act_timeout`)和 4 个布尔标志(`act_started_`、`act_triggered_`、`feedback_triggered_`、`feedback_done_`)中,状态转换路径难以追踪。
**解决方案**:创建 `FbStateMachine` 类,将 7 个状态Idle → Started → InProgress → Done/NotHold/Timeout显式建模变量快照/累积/清零作为状态转换的一部分。
### 1.3 消除 exp_type_ 类型码分支
**根因**5 种算法类型Alg 1-5共用 ExpBase::mon_proc(),通过 `exp_type_` 字段的 16 处条件分支区分行为。
**解决方案**:创建 4 个算法子类LogicAlg、BoundAlg、BoundHoldAlg、FeedbackAlg通过多态的 `doMonProc()` 消除类型码。
---
## 二、新增组件
### 2.1 ExpressionEngine统一表达式引擎
**文件**`eqpalg/utility/expression_engine.h` / `.cpp`347 行)
**职责**
- 所有命名表达式的注册与求值("act"、"feedback"、"result"、"pre_result"、"sample_X"、"sample_Y"、"dataX" 等)
- 唯一的 FunVars 实例(消除双 FunVars 冲突)
- 统一的变量刷新(从共享内存 / iHyperDB
- hold(n,T) 变量管理
- FunVars 延迟重置控制autoReset / markNeedReset / forceReset
**替代**ExpModule已删除 + ExpBase 的表达式管理代码。
### 2.2 FbStateMachine反馈状态机
**文件**`eqpalg/utility/fb_state_machine.h` / `.cpp`348 行)
**职责**
- 7 状态显式转换Idle → Started → InProgress → Done / NotHold / Timeout
- 动作期间的变量快照snapshotActionStart和累积更新updateActionVars
- 超时检测(含 -32768 防溢出哨兵)
- keep_mode 下触发条件丢失处理
- funVars 重置信号输出
**替代**ExpBase 的 `act_start_done` / `act_not_hold` / `act_done` / `act_timeout` + 4 个布尔标志。
### 2.3 BoundChecker上下限检测器
**文件**`eqpalg/utility/bound_checker.h` / `.cpp`90 行)
**职责**
- 4 种检测模式(双侧 / OnlyLeft / OnlyRight / ErrorMode
- 哨兵值 -32768/32767/32768 自动推导检测模式
- `isOutOfBounds(value)` 统一接口
**替代**ExpBase::detect_up_down() + detect_mode_ / limit_down_ / limit_up_。
### 2.4 StatCollector统计学习收集器
**文件**`eqpalg/utility/stat_collector.h` / `.cpp`206 行)
**职责**
- DAA::STA 分布统计生命周期管理
- cron 进程样本批量处理processCron
- 置信区间从 DB2 加载reloadCiDist
- 统计删除与重置reset
**替代**ExpBase::cron_proc() 中的 STA 管理逻辑 + reload_ci_dist()。
### 2.5 算法子类
| 类 | 文件 | 行数 | 对应 Alg ID |
|----|------|------|------------|
| LogicAlg | `algs/logic_alg.h/.cpp` | 36 | 1实时逻辑判断 |
| BoundAlg | `algs/bound_alg.h/.cpp` | 85 | 2监控变量-上下限) |
| BoundHoldAlg | `algs/bound_hold_alg.h/.cpp` | 76 | 5持续超限监控 |
| FeedbackAlg | `algs/feedback_alg.h/.cpp` | 132 | 3/4动作反馈 |
---
## 三、删除项
| 删除项 | 原位置 | 替代 |
|--------|--------|------|
| ExpModule 类 | `utility/ExpModule.h/.cc`250 行) | ExpressionEngine |
| `is_exp_alg_` 标志 | AlgBase + ExpModule 引用传递链 | 无需替代 |
| `exp_act_` / `exp_feedback_` / `exp_result_` | ExpBase 成员 | `expr_engine_->evaluate("act"/"feedback"/"result")` |
| `fun_vars_`ExpBase 副本) | ExpBase 成员 | ExpressionEngine 内部唯一实例 |
| `act_start_done/not_hold/done/timeout` | ExpBase 4 个方法 | FbStateMachine::update() |
| `act_started_/triggered_/fb_triggered_/fb_done_` | ExpBase 4 个布尔标志 | FbStateMachine 内部状态枚举 |
| `m_timemode` | ExpBase 成员 | FbStateMachine::isTimeMode() |
| `refresh_exp_vars_mem/ihd` | ExpBase 方法 | ExpressionEngine::refreshFromMemory/refreshFromIhdRow |
| `first_fill_mm_vars` | ExpBase 方法(~110 行) | ExpressionEngine::firstFill |
| `auto_fun_vars_reset` | ExpBase 方法 | ExpressionEngine::autoResetFunVars |
| `detect_up_down` | ExpBase 方法 | BoundChecker::isOutOfBounds |
| `exp_type_` 分支16 处) | ExpBase::mon_proc/init/exec_task 等 | 算法子类多态 |
---
## 四、ExpBase 瘦身效果
| 指标 | 重构前 | 重构后 | 变化 |
|------|--------|--------|------|
| exp_base.h 行数 | 368 | 269 | -27% |
| exp_base.cpp 行数 | 1588 | 836 | -47% |
| 总行数 | 1956 | 1105 | **-43%** |
| exp_type_ 类型码分支 | 16 处 | 0 | 消除 |
| 布尔状态标志 | 12 个 | ~3 个 | -75% |
| mon_proc() 行数 | 195 | 7 | -96% |
| 方法总数 | 40+ | ~20 | -50% |
---
## 五、测试
新增 77 个单元测试,分布在 3 个测试文件:
| 测试文件 | 用例数 | 覆盖组件 |
|----------|--------|---------|
| `test/test_expression_engine.cc` | 14 | 表达式注册/求值、FunVars、多表达式、变量刷新 |
| `test/test_fb_state_machine.cc` | 11 | 7 状态转换、变量快照/累积、超时、NotHold、forceReset |
| `test/test_algorithms.cc` | 52 | LogicAlg、BoundAlg含 BoundChecker、BoundHoldAlg、FeedbackAlg、ExpTimes、FaultCode gitbit、Roller3 median/extractTagNumbers |
测试框架沿用 RNG 子项目的轻量级 harness`test_harness.h`),无 Boost.Test 依赖。
---
## 六、架构变更图
```
BEFORE AFTER
════════ ════════
AlgBase AlgBase
├── ExpModule (PRR only) └── ExpressionEngine (所有表达式)
├── is_exp_alg_ (补丁标志)
ExpBase (1956行) ExpBase (1105行, 薄抽象层)
├── exp_act_/exp_fb_/exp_res_ ├── doMonProc() = 0 (纯虚)
├── fun_vars_ (副本1) ├── ExpressionEngine& (继承)
├── 变量刷新 (副本1) ├── FbStateMachine
├── 反馈状态机 (4方法+4标志) ├── BoundChecker
├── 上下限检测 ├── StatCollector
├── 统计学习 └── doInitExtend() (钩子)
├── 16处 exp_type_ 分支
│ LogicAlg (36行) — Alg 1
ExpModule (250行) BoundAlg (85行) — Alg 2
├── fun_vars_ (副本2) BoundHoldAlg (76行) — Alg 5
├── 变量刷新 (副本2) FeedbackAlg (132行) — Alg 3/4
└── is_exp_alg_& (告诉它闭嘴)
```
---
## 七、编译修复12 个 commit
重构后首次在 CentOS 7 / GCC 10.2 上编译,逐轮修复了以下问题:
| 问题 | 修复 | commit |
|------|------|--------|
| 测试 target 缺少 include 路径 | 补全 legacy/include/ihdb/memcache/iXcom | 3f10d4d |
| 测试文件 `"test_harness.h"` 不符项目规范 | 统一改为 `<>` 风格 | 4032ff9 |
| 第三方代码 `GlobDefine.h` 大量 format 警告淹没错误 | 添加 5 个 `-Wno-*` 标志 | 5a026ac |
| `enum class DetectMode``ostream<<` | CHECK_EQ 改 CHECK(==) | dc26b6a |
| `mix_cc::time_range_t` 未声明 | expression_engine.h 添加 `<mix_cc/ihyper_db.h>` | 62a2e55 |
| ExpTimes/Roller2/ExpSample2D 等 5 子类未实现纯虚 `doMonProc()` | 添加桩实现 | 18a5675 |
| `bound_alg.cpp` 访问私有 `exps_` | 新增 `hasExpression()` 公有方法 | 43c545e |
| exp_bound/exp_times/exp_sample2D/roller2/roller3 残留旧方法调用 | 逐文件替换为 ExpressionEngine API | ba0bf8c |
| roller3 中 DetectMode 赋值和 LOG 输出 | 添加 `static_cast` | 367802f |
| roller2/roller3 中 init_hold_exp_str/exp_messy_code_check | 改用 registerExpression | 06ebc21 |
---
## 八、Commit 历史
```
#### Phase 1: ExpressionEngine 统一表达式引擎
ec8e44c test: 为 eqpalg 添加测试基础设施
2f7ca1e feat: 添加 ExpressionEngine 头文件声明
da9eb2e feat: ExpressionEngine 核心实现
5017368 feat: ExpressionEngine 变量刷新实现
e575efd feat: ExpressionEngine FunVars 控制 + hold 变量管理
693d3b5 feat: ExpressionEngine firstFill + printVars 实现
f10da49 test: ExpressionEngine 单元测试用例
96ca4d0 refactor: AlgBase 从 ExpModule 迁移到 ExpressionEngine
7c2fe7f refactor: ExpBase 表达式管理迁移到 ExpressionEngine
38d0942 refactor: 非 ExpBase 算法适配 ExpressionEngine API
3f8d281 fix: 清理 ExpBase 子类残留引用
e9b2c17 refactor: 删除 ExpModule 类
#### Phase 2: FbStateMachine 反馈状态机
f2f6d6f feat: 添加 FbStateMachine 头文件
9f66fc1 feat: FbStateMachine 状态转换 + 变量操作实现
fad4ee8 test: FbStateMachine 状态转换单元测试
0106e55 refactor: 集成 FbStateMachine 到 ExpBase::mon_proc()
c4bcb66 refactor: 删除旧反馈状态方法和标志
#### Phase 3: ExpBase 解耦 + 算法子类化
b9cf5f4 refactor: 提取 BoundChecker 上下限检测组件
4f8eecd refactor: 提取 StatCollector 统计学习组件
ae7834a refactor: 算法子类化 — 消除 exp_type_ 分支
032f0d0 refactor: 切换 build_algorithm 工厂到算法子类 + CMake 更新
#### Phase 4: 单元测试 + 文档
ca2147e test: 核心算法单元测试
153ce64 docs: 添加 2026-05-15 eqpalg 重构变更文档
#### 编译修复CentOS 7 / GCC 10.2
3f10d4d fix: 为 eqpalg_test 添加缺失的 include 路径
4032ff9 fix: 将测试文件中 "" include 改为 <> 风格
2754b7a docs: 添加 eqpalg 测试说明文档
5a026ac build: 添加 -Wno-unused-parameter/variable/sign-compare/reorder
dc26b6a fix: 将 enum class 类型的 CHECK_EQ 改为 CHECK(==)
62a2e55 fix: expression_engine.h 添加 <mix_cc/ihyper_db.h>
18a5675 fix: 子类实现 doMonProc() + 测试 CMake 添加缺失链接文件
43c545e fix: 添加 hasExpression(),修复 bound_alg/exp_bound 编译错误
ba0bf8c fix: 清理 ExpBase 子类中残留的旧方法调用
367802f fix: roller3.cpp 中 DetectMode enum class 的 LOG 输出和 stoi 赋值 cast
06ebc21 fix: roller2/roller3 中 init_hold_exp_str/exp_messy_code_check 改用 ExpressionEngine
```