我几次用C ++编写了一个通用的内存中B + Tree实现,我正在考虑让它在磁盘上持久化(这就是为什么B + Tree最初设计的原因)。 我的第一个想法是使用mmap(我在Linux下)能够将文件作为普通内存操作,只需重写我的节点类的 new 运算符,以便它返回映射部分中的指针并创建一个智能指针,可以将RAM地址转换为文件偏移量,以便将我的节点与其他节点链接起来。 但我希望我的实现是通用的,因此用户可以在B +树中存储int,std :: string或他想要的任何自定义类。 这就是问题发生的地方:对于不包含指针的原始类型或聚合类型都是好的,但只要对象包含指向堆分配对象的指针/引用,这种方法就不再有效。
所以我的问题是:是否有一些已知的方法来克服这个困难?我对该主题的个人搜索最终没有成功,但也许我错过了一些东西。
答案 0 :(得分:4)
据我所知,有三种(有点)简单的方法可以解决这个问题。
方法1 :写一个std::streambuf
指向一些预先分配的内存。
这种方法允许您使用operator<<
并使用现有的任何代码来获取您想要的字符串表示。
operator<<
如何吐出内容。方法2 :编写自己的(多次重载)输出函数。
方法3 :撰写btree_traits<>
模板。
btree_traits<>
请求使用operator<<
?答案 1 :(得分:0)
你不能写一个真正通用和透明的版本,因为如果一个非平凡的项目中的指针被分配了malloc(或new和new []),那么它已经在堆中了。
非透明溶胶可能是序列化类是一种选择,这可以相对容易地完成。在存储类之前,您必须调用序列化函数,然后在调用它之前调用反序列化函数。 Boost具有良好的序列化功能,您可以使用B + Tree。
答案 2 :(得分:0)
以通用方式处理指针和引用意味着您需要检查您要存储的结构的类型及其字段。 C ++是一门以其反思而闻名的语言。
但即使在具有强大反思的语言中,这个问题的通用解决方案也很困难。您可能能够使用它来处理更高级语言(如Python,Ruby等)中的子集类型。相关且更强大的范例是persistent programming language。
您想要的功能通常是通过将编写数据块的责任委派给目标类型本身来实现的。它被称为serialization。它只是意味着使用转储数据的方法编写接口,以及加载数据的方法。任何想要保存在B树中的类只需实现此接口。