eis/eqpalg/eqpalg_changes_2026-05-15.md

238 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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
```