我正在寻找一种算法/数据结构,该算法/数据结构适用于基于大型块的设备(例如,机械硬盘驱动器),该设备针对插入,获取,更新和删除进行了优化,其中始终使用数据ID进行搜索,以及在哪里进行搜索任何ID的数据字段的长度都是可变的。
B树似乎是一个常用的结构,但主要用于固定长度的记录。与插入和删除相比,我还期望获得和更新的数量会大大增加。我可以摆脱B树的O(log m)查找吗?
我很高兴能成为一个组合系统,例如,ISAM结合了B树和线性文件存储,这似乎可以使其与可变长度记录一起使用。有更好的东西吗?
一些其他限制:
1)ID可能稀疏,但可以使它们以线性数字块出现-但范围较大(64位)
2)我不想使用DBMS,但针对我的特定问题的性能尚未证明非常好。我不需要完整的DBMS使用的任何操作,也不需要搜索。我需要可以轻松调整和优化的内容。称其为学术上的好奇心,如果它是MySQL所无法完成的,那我会用它,但我必须尝试并加快步伐。
3)数据集大于可容纳在内存中的数据集,但是如果索引与键,偏移量一样简单,则索引很可能适合于内存。我当然正在寻找大约10亿个实体或更多的存储空间。
4)理想情况下,删除记录时应恢复空间。那可能是通过压缩,但是我很想看看是否有更好的方法(例如,一个B树很容易恢复空间)。
自己动手的方式:使用协议缓冲区(或您选择的二进制格式)来定义B树节点和数据项结构。对数据库使用仅附加文件。要写入新记录或修改现有记录,您只需将记录本身写入文件末尾,然后写入任何已修改的B-Tree节点(例如,记录的父节点,
its父节点等等)直到根)。然后,将树的新根的位置写入文件开头的标头块中。要读取文件,您只需找到最新的根节点并像读取其他任何文件一样读取B树。这种方法有几个优点:
您可以通过将索引(即{“逻辑ID”映射到“物理位置”}值对)存储在哈希映射中(散列在逻辑上,从而摆脱对B树的任何O(log m)查找。 ID)...,或者甚至将索引存储在连续的向量中(逻辑ID用作偏移值向量的索引),如bdonlan建议的那样,如果ID值不稀疏。
一个重要的实现细节可能是您用来访问索引的API:是否将其存储在RAM中(O / S随系统页面文件一起支持)并使用指针在进程中对其进行访问,和/或存储它放在磁盘上(O / S缓存在文件系统缓存中)并使用文件I / O API对其进行访问。