目标是建造非常大的树木。 非常大,我的意思是数亿个节点,适合几千兆字节。
问题是常见的数据结构有太多的开销。我不能拥有“节点”对象和儿童“地图”。我需要以非常紧凑的方式将其直接编码到内存中。
因此,我想知道是否存在一些内存有效的实现具有整数作为键和值的树,而不在内部使用对象,因此需要(4个字符用于键+ 4个字节用于值+ 4个字节用于子索引+一些自由散列空间的字节数=平均每个条目15个字节)这将允许我使用外部映射int< - >键和int< - >值来搜索树。
任何?
PS:在内部使用对象至少使用5倍的空间:8个引用+ 4个额外的哈希空间+ 16个对象标题+ 8个键ref + 8个值ref + 8个父级ref + 8个孩子ref +(16 + x)for children map obj =每个条目接近76 + x个字节。 (例如,我们的默认实现需要每个条目大约100个字节)
答案 0 :(得分:2)
这实际上不是Java特定的问题,而是更多的一般概念。
试试这个:http://webdocs.cs.ualberta.ca/~holte/T26/tree-as-array.html
关键是使用基元数组,以避免对象开销。
答案 1 :(得分:2)
我不知道任何具体的树实现,但VTD-XML在内部使用带有指针到缓冲区的标记数组表示XML树(DOM)。也许你可以从他们的解决方案中获得灵感?
答案 2 :(得分:1)
你可能会发现这个库可以帮助你实现你想要的 - 它专门用于存储值作为基元,并在幕后做一些字节码hackery以给出存储对象的错觉。在......时使用它。
...您希望在内存中有效存储大量数据。该库可以显着减少完整GC时间并减少内存消耗。
它没有特定的树集合,但它可能会起作用,具体取决于您的需要。
答案 3 :(得分:1)
我认为您不会找到任何已经实现的内容,但您所描述的内容可以使用IntBuffer轻松实现。您将创建一个“包装器”类,将索引转换为缓冲区中的记录,并根据需要实例化/丢弃这些包装(即,当您遍历树时,您可能不在乎关于持有对父母的引用。)
有几个问题:
TreeMap
等类为您完成了这项工作。但算法非常简单,可从Wikipedia获得。答案 4 :(得分:0)
每个节点都可以引用其父节点,而不是保留子节点列表。因此,序列化节点不需要超过三个整数值(父,键,值)。
这种方法的一个问题是树遍历。获取所有节点子节点的确定列表将需要遍历所有节点。如果tripplettes按其父值排序,则可以改进遍历。添加一个整数值,即指向下一个键的指针,可以使节点保持在链表中,从而简化了节点插入和删除的工作。