C++ B+;具有可变长度键的树

C++ B+;具有可变长度键的树,c++,data-structures,tree,b-tree,C++,Data Structures,Tree,B Tree,在B+树的常见实现中,我们可以假设密钥具有固定长度(例如25字节)。然后,我们可以定义每个节点必须具有最少数量的键,以及最大数量的键 如果我想让树接受可变长度的键,我应该修改什么?如果我说节点必须至少有2个键,但我尝试插入的键太大,无法放入保存节点的块中,该怎么办?使用哈希。散列是密钥的固定大小表示形式。有关良好的散列函数,请参见。简单的解决方案是将键存储为指针(封装在覆盖相对运算符等的类型中),而不是值,但这当然会破坏使用B+树的局部性 也就是说,项目越大,项目在内存中是否相邻就越不重要。一个

在B+树的常见实现中,我们可以假设密钥具有固定长度(例如25字节)。然后,我们可以定义每个节点必须具有最少数量的键,以及最大数量的键


如果我想让树接受可变长度的键,我应该修改什么?如果我说节点必须至少有2个键,但我尝试插入的键太大,无法放入保存节点的块中,该怎么办?

使用哈希。散列是密钥的固定大小表示形式。有关良好的散列函数,请参见。

简单的解决方案是将键存储为指针(封装在覆盖相对运算符等的类型中),而不是值,但这当然会破坏使用B+树的局部性

也就是说,项目越大,项目在内存中是否相邻就越不重要。一个缓存页面中甚至一个都放不下大型项目,更不用说同一页面中的多个了

另一个相对简单的方法是使用union类型或placement new或其他方法在内存中为条目类型分配条目,该条目类型对于您可能使用的所有条目类型都足够大。每个项目仍然有固定的字节数,但项目不一定使用所有这些字节

如果你愿意做这项工作,你可以有不同大小的节点。当然,处理这些节点时会遇到一些麻烦,这取决于如何安排节点内数据结构来处理这些问题。例如,节点内可能有一个小的项目指针数组,指向节点内的项目(不是在堆上单独分配的)

此外,每次更改节点时,您可能需要重新分配它。即使您所做的只是重新平衡,这也可能会将一个巨大的项目从一个节点移动到另一个节点,并且即使目标节点有空间(即项目有一个可用插槽),它也可能没有足够的字节来存储值

从某种意义上说,每个节点都是一个小型堆,您可以在其中为大小项目分配或释放空间,但有时您必须返回到适当的堆,以用较大或较小的堆替换该小型堆

再次值得一提的是,如果项目如此庞大,那么节点中的位置可能根本不相关


我以前在内存中实现过B+风格的多路树,但我从来没有走到过这个极端。

你可以将一个大键的其余部分保存在溢出页中,比如。

如果在一个块中没有至少按两个键分组,B+树将无法有效地处理这些键。通常一个键的大小是合理的(我猜最多100字节)。嗯?我无法在树上保存哈希值。。如果两个键散列到同一个值怎么办?我怎样才能在树上找到它们?@l19:当然可以。您只需要添加指向键值对的指针,该键值对本身具有指向下一个(链表)的指针。搜索特定键时,在树中找到其哈希,然后沿着链移动比较键。在这一点上,您可以只使用哈希表,在任何情况下都比B+树快。使用B+树的主要原因是,您需要能够提取一个键的两个值之间的条目(子范围查询),甚至可以按顺序列出所有条目。