zoukankan      html  css  js  c++  java
  • Graph database_neo4j 底层存储结构分析(6)

    3.6  Node 数据存储

    neo4j 中, Node 的存储是由 NodeStore 和 ArrayPropertyStore 2中类型配合来完成的. node 的label 内容是存在ArrayPropertyStore这样的DynamicStore 中,如果长度超过一个block ,则分block存储,并将其在ArrayPropertyStore中的第1个block 的 block_id 保存到 NodeStore类型文件相应record 的labels字段中。

    下面是neo4j graph db 中,Node数据存储对应的文件:

    neostore.nodestore.db

    neostore.nodestore.db.id

    neostore.nodestore.db.labels

    neostore.nodestore.db.labels.id

    ArrayPropertyStore的存储格式见< 3.3.2 DynamicStore 类型>,下面介绍一下 NodeStore 的文件存储格式。

    3.6.1   NodeStore的主文件存储格式

    NodeStore的主文件是neostore.nodestore.db, 其文件存储格式示意图如下,整个文件是有一个 RECORD_SIZE=15Bytes  的定长数组和一个字符串描述符“NodeStore v0.A.2”(文件类型描述TYPE_DESCRIPTOR和 neo4j 的 ALL_STORES_VERSION) 构成。访问时,可以通过 node_id 作为数组的下标进行访问。

    neo4j_文件存储格式_NodeStore--20140410

    neo4j_存储模型_node--20140410
    1
    2
    3
    4
    5
    &lt;div&gt;
     
    // in_use(byte)+next_rel_id(int)+next_prop_id(int)+labels(5)+extra(byte)
     
    public static final int RECORD_SIZE = 15;

    下面介绍一下 node record 中每个字段的含义:

    • n  inUse(1 Byte):第1字节,共分成3部分

    // [pppp,rrrx]

    // [    ,   x] in use bit

    // [    ,rrr  ] higher bits for rel id

    // [pppp,    ] higher bits for prop id

    long inUseByte = buffer.get();

      1. 第1 bit 表示 record 是否在 use;
      2. 第2~4 bit 表示 node 的第1个 relationship_id 的 高3位;
      3. 第 5~8 bit表示 node 的第1个property_id 的 高4位
    • next_rel_id(4 Bytes) : 第2~5字节是node 的第1个 relationship_id 的 低32位. 加上inUse 字节的第 2~4 bit作为高3位,构成一个完整的35位relationship_id。
    • next_prop_id(4 Bytes) : 第6~9字节是node 的第1个 property_id 的 低32位. 加上inUse 字节的第 5~8 bit作为高4位,构成一个完整的36 位 property_id。
    • labels(5 Bytes) : 第10~14字节是node 的label field。
    • extra(1 Byte) : 第15字节是 extra , 目前只用到第 1 bit ,表示该node 是否 dense, 缺省的配置是 该 node 的 relationshiop 的数量超过 50 个,这表示是 dense.

    3.3.2   NodeStore.java

    neo4j 中与neostore.nodestore.db文件相对应的类是NodeStore,负责NodeRecord在neostore.nodestore.db文件中的读写。

    下面看一下 NodeStore.java 中 getRecord 成员函数,可以帮助理解 Node Record 的存储格式。

    1
    <br />&lt;div&gt;<br /><br />private NodeRecord getRecord( long id, PersistenceWindow window,<br /><br />RecordLoad load  )<br /><br />{<br /><br />Buffer buffer = window.getOffsettedBuffer( id );<br /><br />// [    ,   x] in use bit<br /><br />// [    ,xxx ] higher bits for rel id<br /><br />// [xxxx,    ] higher bits for prop id<br /><br />long inUseByte = buffer.get();<br /><br />boolean inUse = (inUseByte &amp; 0x1) == Record.IN_USE.intValue();<br /><br />if ( !inUse )<br /><br />{<br /><br />switch ( load )<br /><br />{<br /><br />case NORMAL:<br /><br />throw new InvalidRecordException( "NodeRecord[" + id + "] not in use" );<br /><br />case CHECK:<br /><br />return null;<br /><br />case FORCE:<br /><br />break;<br /><br />}<br /><br />}<br /><br />long nextRel = buffer.getUnsignedInt();<br /><br />long nextProp = buffer.getUnsignedInt();<br /><br />long relModifier = (inUseByte &amp; 0xEL) &lt;&lt; 31;<br /><br />long propModifier = (inUseByte &amp; 0xF0L) &lt;&lt; 28;<br /><br />long lsbLabels = buffer.getUnsignedInt();<br /><br />long hsbLabels = buffer.get() &amp; 0xFF; // so that a negative byte won't fill the "extended" bits with ones.<br /><br />long labels = lsbLabels | (hsbLabels &lt;&lt; 32);<br /><br />byte extra = buffer.get();<br /><br />boolean dense = (extra &amp; 0x1) &gt; 0;<br /><br />NodeRecord nodeRecord = new NodeRecord( id, dense, longFromIntAndMod( nextRel, relModifier ),<br /><br />longFromIntAndMod( nextProp, propModifier ) );<br /><br />nodeRecord.setInUse( inUse );<br /><br />nodeRecord.setLabelField( labels, Collections.&lt;DynamicRecord&gt;emptyList() );<br /><br />return nodeRecord;<br /><br />}<br /><br />

     

  • 相关阅读:
    不可或缺 Windows Native (15)
    不可或缺 Windows Native (14)
    不可或缺 Windows Native (13)
    不可或缺 Windows Native (12)
    不可或缺 Windows Native (11)
    不可或缺 Windows Native (10)
    不可或缺 Windows Native (9)
    不可或缺 Windows Native (8)
    不可或缺 Windows Native (7)
    不可或缺 Windows Native (6)
  • 原文地址:https://www.cnblogs.com/gisblogs/p/4545766.html
Copyright © 2011-2022 走看看