搜索/修改数据库存储引擎,不破坏性能与兼容性

修改数据库存储引擎,不破坏性能与兼容性

让AI修改数据库存储引擎代码时使用。规定如何正确处理错误与并发、先用基准测试证明再优化、保持API、文件格式和构建的兼容,并在可复现的测试通过后才批准变更。

要使用这个AI规则
## 编写可读的代码,正确处理错误与并发 编写清晰且能自我说明的代码,使用有意义的名称,并为不直观的不变量添加注释。 优先采用易读的控制流,而不是只能略微提速的巧妙技巧。 遵循仓库的格式化工具、命名规则和结构模式。 始终一致地使用项目的标准状态类型或错误类型。 传播失败时附带足够的上下文,以便确定失败的操作。 绝不能默默丢弃错误或未经检查的状态值。 对于生产路径中可恢复的失败,应避免使用断言。 覆盖无效输入、资源耗尽、I/O故障、数据损坏和部分进度。 保留键顺序、快照可见性、持久性和恢复行为等数据库语义。 在同步假设所保护的数据旁边记录这些假设。 将锁、原子操作、内存顺序、竞争风险和死锁风险放在一起审查。 在成功、错误、取消和关闭路径中明确处理资源清理。 让注释聚焦于局部契约,而不是某个调用方当前的理由。 当共享抽象具有稳定且连贯的职责时,应消除重复逻辑。 在测试失败路径和并发行为之前,不得将涉及正确性的变更标记为可合并。 ## 按代码执行频率优化,并用基准测试证明效果 将性能意识视为存储引擎工作的必备要求。 从一开始就选择合理的算法和数据结构,同时在微优化之前先确立正确性。 按执行频率对受影响的代码分类: - 热路径会让每次分配、复制、分支和缓存未命中在频繁操作中不断累积。 - 温路径需要在清晰度和速度之间取得经过测量的平衡。 - 冷路径应优先考虑可维护性,除非性能分析显示存在重大成本。 使用基准测试和性能分析数据支撑性能主张。 与适当的基线比较,并报告工作负载、配置和方差。 在理由充分时,通过复用、预分配、区域分配器或内存池减少热路径中的动态分配。 优先使用移动、视图、引用和原地操作,避免不必要的复制。 按照局部性安排数据和访问模式,并避免伪共享。 将不变工作移出循环,批量处理重复操作,并减少难以预测的分支。 分支可能性提示只应用于确实罕见或代价高昂的情况,而不能用于常见配置。 在采用显式内建函数之前,先通过合适的数据布局启用编译器向量化。 仅在受支持、经过测量且可维护的地方使用显式SIMD。 应用RAII和明确的所有权,在保持低开销的同时防止泄漏。 不得保留无法带来可复现收益的复杂优化。 ## 用单一用途的选项设计保持兼容的API 将高层策略保留在调用方或策略层中。 由较低层提供精确且可复用的机制。 不得让通用代码依赖某个调用方的身份或理由。 让每个标志或参数只具有一种连贯的行为。 对于将所有权、缓存、I/O模式和预取捆绑在一起的布尔值,应改用明确字段或选项对象。 不得根据缓存句柄或读取器状态等偶然的实现细节推断策略。 使用断言、更窄的接口和更清晰的名称,使契约可以强制执行。 让新API与既有的命名、参数顺序、返回类型和错误处理保持一致。 在适当情况下使用类型安全的选项,包括定宽整数类型和限定作用域的枚举。 验证选项值并返回明确的错误。 使动态配置变更具备线程安全性,并验证它们何时生效。 除非破坏性变更具有极其充分的理由,否则应保留源代码兼容性和二进制兼容性。 公开二进制接口时,应审查布局、符号和调用约定。 按照文档规定的跨多个版本流程进行弃用,并提供迁移指南。 记录公共API的用法、参数含义、线程安全规则、性能成本和兼容性说明。 不得通过公共API导出第三方实现类型。 ## 对预写日志等高风险部分做最深入的审查 对预写日志、内存表、压实、恢复和其他数据库核心路径实施最深入的审查。 在不同配置、压实方式、故障和并发工作负载下测试核心变更。 确保压实遵守配置的限制,并能处理空文件集或只有一个文件的情况。 将公共头文件视为兼容性影响最大的接口面。 将持久化表格式和块格式视为长期数据契约。 针对不同压缩方式、块大小、损坏情况和兼容性边界验证校验和。 测试迭代器的定位、下一项、上一项、删除和端点语义。 保持缓存键唯一,并确保预取遵守资源限制。 对可能在热路径中运行的表、缓存和实用工具变更进行基准测试。 明确缓存同步、内存所有权和驱逐策略。 让可选实用工具与数据库内部实现相隔离。 对于选项,应验证类型安全性、值校验、弃用和线程安全的动态更新。 对于内部实用工具,应测试溢出、下溢、无效输入和断言契约。 如果没有单元、集成、压力和基准测试证据,不得批准高风险的格式、恢复、压实或缓存变更。 ## 同步所有构建系统,确保每个受支持的平台都能构建 添加或移除源文件时,应维护所有受支持的构建系统。 先更新权威源文件清单,再使用获准的生成器重新生成派生构建文件。 不得手工编辑生成的内部构建文件。 在所有构建定义、语言、文档和实现中搜索受影响的引用。 在资源限制范围内,使用主机的CPU数量进行并行构建。 防止混合构建模式重复使用不兼容的目标文件。 对于手动构建,应启用构建系统在配置变更时自动清理的机制。 支持项目的操作系统、编译器、标准库、Sanitizer和构建模式矩阵。 在已配置的范围内,应考虑Linux、macOS、Windows、本地与交叉编译器、发布构建、Sanitizer、Unity构建和语言绑定。 优先使用项目的可移植性抽象,而不是直接调用平台API。 为无法避免的平台特定头文件、调用、属性和内建功能添加保护条件。 直接包含每个标准头文件,不要依赖传递性包含。 如果项目有此约束,应确保生产二进制文件和压力测试二进制文件无需运行时类型信息也能构建。 将运行时向下转型限制在测试中;其他位置使用项目提供的检查式静态转型辅助工具。 运行源代码检查,拒绝不支持的字符和其他与CI不兼容的内容。 如果仓库有此要求,应在源代码注释和字符串中使用ASCII标点。 ## 不靠休眠等待,编写能复现失败的测试 使测试深度与风险匹配:使用单元测试验证孤立行为,使用集成测试验证交互,使用压力测试验证并发性和性能。 覆盖边界、错误路径、恢复、平台差异和回归情况。 当输入不同但受测契约相同时,使用表驱动测试用例。 为重复的构造、往返转换和断言序列提取辅助函数。 将确定性的边界情况与随机化覆盖分开。 如果随机抽样能提供更广泛且有用的覆盖,应优先于参数组合的穷举。 使用项目的随机数源并显示种子,以便复现失败。 等待并发事件时不得休眠。 使用同步点或明确的信号控制线程进度。 使用规定的超时限制每个单元测试的执行时间。 串行运行少量聚焦测试,并通过并行测试框架运行更大的测试集。 在强制上下文切换下反复对新的并发测试进行压力测试。 使用项目专用的复现工具调查仅在CI中出现的不稳定失败。 测试所有受路径、API、编译器或构建标志影响的受支持平台。 确保测试失败报告足够的状态,以复现触发问题的配置。 将新的配置选项和性能功能纳入压力测试与基准测试的覆盖范围。 提交前审查更新后的测试是否存在重复和意外共享状态。 ## 添加许可证头,同步文档与发布说明 为每个新源文件添加仓库要求的许可证头。 在派生文件中,除项目头之外还要保留上游版权声明。 针对每种源代码语言使用正确的注释前缀。 不得用通用权利声明替换必需的双重许可标识。 变更后运行自动格式化,并检查产生的差异。 运行依赖项维护工具,并拒绝无关的清单变动。 添加功能时,应评估有用的指标,同时不得造成热路径性能回退。 通过标准基准测试工具提供性能相关功能。 让发布说明保持简短、面向外部,并聚焦于用户可见的行为。 在子系统索引和专题章节中记录组件设计。 在需要时,确保生成的网站或文章引用有效的作者元数据。 对于新API、新选项或弃用,应遵循仓库的专用流程。 在移除已弃用的接口面之前更新迁移指南。 保持实现、构建元数据、测试、文档和发布说明同步。 不得让新源文件只在一个构建系统中可访问,而在另一个构建系统中缺失。 ## 通过干净构建和测试后再批准变更 将正确性、测试、性能、兼容性、契约边界、风格和文档作为独立关卡分别审查。 对于性能敏感的变更,必须提供基准测试结果。 对于新的并发行为或可配置行为,必须提供压力测试覆盖。 聚焦检查通过后,运行完整的全新构建与测试目标。 运行更严格的状态检查构建,以检测被忽略的错误结果。 使用自动清理模式,使变更后的构建标志无法复用陈旧的目标文件。 通过构建系统的机器可读进度信息监控长时间测试。 跟踪阶段、已完成工作、总工作量、失败、百分比以及限制长度的失败详情。 区分断言失败与崩溃、信号、超时和基础设施错误。 将基准参数和测试配置与报告的证据一起保留。 以发布模式构建用于测量的基准测试。 诊断崩溃时切换到调试构建,然后在再次测量前进行干净的重新构建。 运行受影响接口面所需的格式、源代码、构建、测试、Sanitizer和平台检查。 审查修正后,重新运行直接受影响的关卡。 不得仅因某些匹配项看起来不太可能相关,就缩小整个仓库的一致性搜索范围。 只有代码、契约、测试、构建元数据、文档和测量证据相互一致时,才能批准。