Skip to main content

Module builder

Module builder 

Source
Expand description

可变的单分子构造器。

架构上刻意与 MolBatch 分开:编辑操作(解析建图、 反应产物构建)需要随意增删原子和键,而列式布局要为此付出高昂代价。 于是分成两段 —— MolBuilder 负责建,MolBatchBuilder::push 收进去之后 进入不可变的列式批, 所有算法都跑在后者上。

§邻接索引

MolBuilder 自带一份始终有效的邻接索引,neighborsdegree 都是 O(度数)。没有它的话,“取某原子的 邻居“只能扫全部键,而化学算法几乎每一步都在做这件事,整体就退化成 O(原子数 × 键数)。

§为什么是半边链表,不是 CSR

MolBatch 用 CSR,因为它不可变、只被扫描。MolBuilder增量构建 的:CSR 每加一条键都要重排整个邻接数组,解析一个 E 条键的分子就变成 O(E·(V+E))。半边链表加边是 O(1),代价是遍历时跳指针 —— 在编辑期的 规模下无所谓,真正吃吞吐的批量算法跑在 MolBatch 上。

这个分工是架构层面的:MolBuilder 为编辑优化,MolBatch 为扫描优化。

§索引不会失效

索引在 add_bond_data 里同步维护,不是缓存, 没有脏标记,也不需要谁记得去刷新。为此 bond_mut 返回的 BondMut 不暴露端点 —— 改端点就是改拓扑,只能走建边接口。

use omgkit_core::{MolBuilder, BondOrder};

// 乙醇 CCO
let mut b = MolBuilder::new();
let c0 = b.add_atom(6);
let c1 = b.add_atom(6);
let o  = b.add_atom(8);
b.add_bond(c0, c1, BondOrder::Single).unwrap();
b.add_bond(c1, o,  BondOrder::Single).unwrap();
assert_eq!(b.num_atoms(), 3);
assert_eq!(b.num_bonds(), 2);

Structs§

AtomData
单个原子的可变数据。
BondData
单条键的可变数据。端点为分子内局部原子下标。
BondMut
键属性的可变句柄,由 MolBuilder::bond_mut 取得。
MolBuilder
可变的单分子构造器。
Neighbors
MolBuilder::neighbors 的迭代器,沿半边链表前进。