• 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 />

     

  • 相关阅读:
    web.xml配置文件详解
    spring MVC配置文件详解
    路由导航刷新后导致当前选中的导航样式不见的解决办法
    vue input 使用v-model想要改变父属性的写法
    JS 编写一个指定范围内的随机数返回方法
    vue-router 3.1.5报错:vue-router.esm.js?8c4f:2089 Uncaught (in promise)
    Failed to mount component: template or render function not defined. vue
    vscode 操作debugger for chrome的配置文件写法
    JS操作DOM方法总结
    npm 代理配置的方法
  • 原文地址:https://www.cnblogs.com/gisblogs/p/4545766.html
Copyright © 2020-2023  润新知