// 代码示意+技术注释
// 核心逻辑:处理单行数据
void process_data_row(char* data_line, T_Tree* cols_list, SdbcDAO* dao) {
ctx_stu ctx;
ctx.p = data_line; // 上下文绑定当前行文本首地址
ctx.dao = dao; // 上下文绑定数据目的缓冲
// 【控制反转点】:让树的遍历来驱动解析。
// BB_Tree_Traverse 内部会按照 col_idx (0, 1, 2...) 的顺序依次访问节点
// 每访问一个节点,就自动调用一次回调函数 fill_cols_callback
BB_Tree_Traverse(cols_list, fill_cols_callback, &ctx);
}
// 树节点的回调函数:这才是真正的“生产车间”
void fill_cols_callback(t_node* node, void* context) {
ctx_stu* ctx = (ctx_stu*)context;
FieldTemplate* tp = node->tp; // 拿到当前列的转换与对齐规则
// 1. 顺着上下文的指针切出当前列的文本(不写死,纯动态消费)
char* token = extract_next_token(&(ctx->p));
if (token == NULL) return;
// 2. 根据基地址 + 节点预存的偏移量,直接定位到物理内存卡槽
void* target_address = ctx->dao->data_area_base + tp->offset;
// 3. 根据节点类型,就地擦写缓冲区,零拷贝直接落库
if (tp->type == TYPE_INT) {
*(int*)target_address = atoi(token);
} else if (tp->type == TYPE_STRING) {
strncpy((char*)target_address, token, tp->length);
}
}
总结:
- 极度内聚的回调逻辑: fill_cols_callback 函数极其纯粹。它不需要知道整体文件有多少列,也不需要知道自己当前处理的是“第几步”,它只关心“我手头的这个节点规则,如何消费当前的一小段字符串,并写入对应的 Offset”。
- 完美的开放封闭原则(OCP): 如果业务上数据库表增加了解析字段,或者调整了字段顺序,数据行的解析代码(process_data_row)一个字都不需要改。变化的只有第一阶段动态生成的二叉树形态。树变了,遍历的次序就变了,内存写入的拓扑自动自适应。这就是高度抽象带来的性能与灵活性的微观统一。
【 在 ylh1969 的大作中提到: 】
: 过奖,我是十年磨一剑慢工细活,愿赠予识货者。
: 现代技术飞速发展,我落伍了,拿出想法,供你们之后需要之时参考,甚幸。
--
FROM 61.185.160.*