索引增长时如何继续定位
本任务检查三个不同的定位状态:有序索引的父指针是否还能安全导向目标,哈希目录的别名是否仍指向正确桶,以及无大目录的哈希表如何辨认哪些桶已拆。旧B+树已有普通叶链范围与回表成本,本单元只沿真实结构增长缺口继续。
先读B-link查找、可扩展哈希与线性哈希。所有页容量与哈希函数都在下面给定,不能把小算例的分布当成随机性能保证。
任务一:先拿到旧子指针,再遇到页分裂
固定高度、单写者、根页足够大,不发生根增高。初态父页以50分隔A/C;A=[10,20,30,40]、H=50、right=C;C=[50,60]、H=∞。页图像整体读取,页ID不回收;只插入,不删除、合并或崩溃。读者查40,已经从旧父取得A。
插入35后先完整准备B=[30,35,40]、H=50、right=C;再一次发布A=[10,20]、H=30、right=B;最后父页登记30→B。逐步列出读者现在读哪个页、为何右移、在哪一页比较完整键。
核对:读父、A、B三页。40≥30让读者离开A;40<50使读者在B比较并命中。父修复后新查40只读父和B。查30也要右移,查29则可在A证明缺失。先截断A而留下旧上界50,会错误遗漏操作开始前就存在的40;先发布right B却不初始化B,会访问未就绪内容。
迁移到内部层:旧根仍指内部页I,I已分为上界50的I及右邻J,J负责50以上子区间。查60必须在I层先右移J,再下降到含60的叶。只在叶层检查high fence的版本不满足本页算法。
进一步让父修复长期延后而连续分裂叶页,记录额外右移次数a。答案应保持正确,但成本为实际的1+h+a次页图像读取;不能把a丢掉后仍承诺严格的对数访问。
任务二:目录翻倍两次,只分裂一个热点区域
桶容量C=2,四位哈希H(k)=k mod16,取低位。初始g=1,目录0指空偶桶、1指空奇桶,两桶局部深度1。按5、9、1、3、7、13插入不同键;每步画目录、物理桶和局部深度。
核对:插1时先把奇桶按低两位拆成01/11,但5、9、1都落01;再按低三位拆成001/101,才分别放下[9,1]与[5]。最终g=3,八项指向四桶:0/2/4/6共指空偶桶(d1),1指[9,1](d3),5指[5,13](d3),3/7共指[3,7](d2)。别名4+1+1+2=8,记录数始终6。
删除13后,101与001合计3条,不能合并;再删9,合计只剩1和5,可合为01/d2,目录缩为g2。继续删7、3,逐次检验同伴与容量,最终g0的一桶保存[1,5]。不能仅因某目录项指向空桶,就合并任意相邻目录下标。
迁移输入1、17、33:四位完整哈希全为1,容量2时第三条失败,原来两条仍可查询。无限增大目录不可能制造第五个哈希位;核验器在修改前检测这个有限模型失败,保持原映射与结构快照。
任务三:没有目录,也必须保留未拆桶的溢出记录
改用线性哈希,初始N0=2、C=2、H(k)=k。仍插5、9、1、3、7、13;固定触发规则为新记录放入溢出部分时,恰好拆一次s指向的桶。
核对分裂:插1时溢出发生在1,却拆0,状态N2/s1;插3才拆1,重分后进入新阶段N4/s0;插13又拆0,最终N4/s1,主桶为0..4。桶1记录[5,9,1,13]占主页面[5,9]与溢出页[1,13],桶3=[3,7],三个其他主桶为空。总数据页为5+1=6。
查13先mod4=1,因为1≥s不做第二次取模;错误地一律mod8会去不存在的5。查4先mod4=0<s,再mod8得到4。两种分支都要执行,不能只验证表中已有键的一个分支。
继续插17,当前s1分裂成1/5:桶1=[9,1,17]仍有溢出,桶5=[5,13]。如果只搬主页面而漏掉旧溢出页,13就会在新寻址下丢失。
从原六键终态另开一次运行,执行两次受控收缩:先合4→0,回到N4/s0;再逆上一阶段最后一次分裂,把3合回1,得到N2/s1和三个主桶。全部六个奇数键仍存在,但桶1需要3页。这说明结构正确和性能合适须分别判断。
三份成本账
- B-link:固定高度h及额外右移a,读1+h+a个页图像;父页滞后不能算免费
- 可扩展哈希:元数据已驻留、目录槽可直接定位时,冷查询至多一个目录槽页加一个桶页;目录翻倍复制指针的更新工作另计
- 线性哈希:地址最多两次取模,但查询还要经过实际溢出链;没有大目录不表示没有额外数据页
原有槽页和缓冲池继续承担物理页布局、驻留和保护责任。这里没有把成功的内存结构改动称为已提交或已持久。
运行与检查范围
下载纯Python核验器,使用Python 3.10或更新版本的普通模式运行。输出三个主轨迹与检查计数;不联网,不启动数据库。-O模式明确拒绝运行,不允许跳过断言后输出成功。
检查器枚举读写交错与延后父修复的查找,随机比较哈希映射、目录别名与容量,另用按已分配桶数折回的公式独立核对线性哈希寻址。日志快照排序、字典拷贝和全表断言属于核验开销,不是正文局部核心更新的成本。
回到索引增长时如何继续定位学习路线,按一次错误定位反查需要修复的状态。