我正在用java实现B Plus Tree。我有一个节点类,我在其中维护对子对象Nodes的引用。现在,当我序列化任何节点时,它也会序列化所有子节点。我想要的是只序列化该节点和对子节点的引用。我尝试将节点对象写入字节流,但在反序列化时它不起作用。
public class BNode implements Serializable
{
LinkedList<Float> keys;
LinkedList<BNode> childPointers;
BNode parent;
...
}
在B+树中,节点保存在磁盘中,我必须模拟该操作。现在每个页面的大小是2KB,所以在我的每个节点中,我将在模拟单个节点的单个文件中保存大约2044字节的数据(255个浮点值和256个节点引用-总共255*4+255*4+一些其他10字节的数据)。现在,如果我序列化父节点,它就是将整个树序列化为单个文件,从而击败了整个目的的
您必须使用transient
。这将从序列化中排除变量。
public class BNode implements Serializable
{
LinkedList<Float> keys;
LinkedList<BNode> childPointers;
transient BNode parent;
...
}
如果您需要更复杂的规则,您可以通过实现以下方法来覆盖(反)序列化的非默认行为:
private void writeObject(ObjectOutputStream out) throws IOException;
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException;
检查http://www.oracle.com/technetwork/articles/java/javaserial-1536170.html以进行深入的描述。
在任何实际的基于磁盘的B树中,每个索引块都需要包含与该块中的键对应的块的磁盘偏移。因此,您需要使引用数组成为瞬态数组,并为偏移添加一个long
的非瞬态数组。
如果可以避免的话,我还建议你不要保留父引用或偏移。如果你记住了每个搜索路径,你就可以避免它。在大树中,当你拆分内部节点时,你不想更新N/2个子节点中的父链接以及你必须做的所有其他事情。这对性能有很大影响。