标签:
下面是neo4j graph db 中,Relationship数据存储对应的文件:
neostore.relationshipgroupstore.db
neostore.relationshipgroupstore.db.id
neostore.relationshipstore.db
neostore.relationshipstore.db.id
neostore.relationshiptypestore.db
neostore.relationshiptypestore.db.id
neostore.relationshiptypestore.db.names
neostore.relationshiptypestore.db.names.id
neo4j 中, Relationship 的存储是由 RelationshipStore , RelationshipGroupStore, RelationshipTypeTokenStore和StringPropertyStore 4种类型的Store配合来完成的. 其中RelationshipStore 是Relationship最主要的存储结构;当一个Node 的关系数达到一定的阀值时,才会对关系分组(group), RelationshipGroupStore 用来保存关系分组数据;RelationshipTypeTokenStore和StringPropertyStore 配合用来存储关系的类型。
关系的类型的字符串描述值是存在StringPropertyStore这样的DynamicStore 中,如果长度超过一个block ,则分block存储,并将其在StringPropertyStore中的第1个block 的 block_id 保存到 RelationshipTypeTokenStore类型文件相应record 的name_id字段中。
ArrayPropertyStore的存储格式见< 3.3.2 DynamicStore 类型>,下面分别介绍一下RelationshipTypeTokenStore, RelationshipStore和RelationshipStore的文件存储格式。
类RelationshipTypeTokenStore对应的存储文件是neostore.relationshiptypestore.db,其对应的存储格式如上图所示:是一个长度为 RECORD_SIZE=5 Bytes 的 record 数组和和一个字符串描述符“RelationshipTypeStore v0.A.2”(文件类型描述TYPE_DESCRIPTOR和 neo4j 的 ALL_STORES_VERSION) 构成。访问时,可以通过 token_id 作为数组的下标进行访问。
record 是有 1Byte的 in_use 和 4Bytes 的 name_id 构成。
类RelationshipTypeTokenStore对应的存储文件是neostore.relationshipstore.db,其文件存储格式示意图如下,整个文件是有一个 RECORD_SIZE=34Bytes 的定长数组和一个字符串描述符“RelationshipStore v0.A.2”(文件类型描述TYPE_DESCRIPTOR和 neo4j 的 ALL_STORES_VERSION构成)。访问时,可以通过 node_id 作为数组的下标进行访问。
| 
 1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
 | 
</pre><div>// record header size// directed|in_use(byte)+first_node(int)+second_node(int)+rel_type(int)+// first_prev_rel_id(int)+first_next_rel_id+second_prev_rel_id(int)+// second_next_rel_id+next_prop_id(int)+first-in-chain-markers(1)public static final int RECORD_SIZE = 34;</div><pre> | 
下面介绍一下 relationship record 中每个字段的含义:
// [ , ][ , ][xxxx,xxxx][xxxx,xxxx] type
与neostore.relationshipstore.db文件相对应的类是RelationshipStore,负责RelationshipRecord从neostore.relationshipstore.db文件的读写。下面看一下 neostore.relationshipstore.db 中 getRecord 成员函数,可以帮助理解 Relationship Record 的存储格式。
| 
 1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
37 
38 
39 
40 
41 
42 
43 
44 
45 
46 
47 
48 
49 
50 
51 
52 
53 
54 
55 
56 
57 
58 
59 
60 
61 
62 
63 
64 
65 
66 
67 
68 
69 
70 
71 
72 
73 
74 
75 
76 
77 
78 
79 
80 
81 
82 
83 
84 
85 
86 
87 
88 
89 
90 
91 
92 
93 
94 
95 
96 
97 
98 
99 
100 
101 
102 
103 
104 
105 
106 
107 
108 
109 
 | 
</pre><div>private RelationshipRecord getRecord( long id, PersistenceWindow window,RecordLoad load ){Buffer buffer = window.getOffsettedBuffer( id );// [    ,   x] in use flag// [    ,xxx ] first node high order bits// [xxxx,    ] next prop high order bitslong inUseByte = buffer.get();boolean inUse = (inUseByte & 0x1) == Record.IN_USE.intValue();if ( !inUse ){switch ( load ){case NORMAL:throw new InvalidRecordException( "RelationshipRecord[" + id + "] not in use" );case CHECK:return null;}}long firstNode = buffer.getUnsignedInt();long firstNodeMod = (inUseByte & 0xEL) << 31;long secondNode = buffer.getUnsignedInt();// [ xxx,    ][    ,    ][    ,    ][    ,    ] second node high order bits,     0x70000000// [    ,xxx ][    ,    ][    ,    ][    ,    ] first prev rel high order bits,  0xE000000// [    ,   x][xx  ,    ][    ,    ][    ,    ] first next rel high order bits,  0x1C00000// [    ,    ][  xx,x   ][    ,    ][    ,    ] second prev rel high order bits, 0x380000// [    ,    ][    , xxx][    ,    ][    ,    ] second next rel high order bits, 0x70000// [    ,    ][    ,    ][xxxx,xxxx][xxxx,xxxx] typelong typeInt = buffer.getInt();long secondNodeMod = (typeInt & 0x70000000L) << 4;int type = (int)(typeInt & 0xFFFF);RelationshipRecord record = new RelationshipRecord( id,longFromIntAndMod( firstNode, firstNodeMod ),longFromIntAndMod( secondNode, secondNodeMod ), type );record.setInUse( inUse );long firstPrevRel = buffer.getUnsignedInt();long firstPrevRelMod = (typeInt & 0xE000000L) << 7;record.setFirstPrevRel( longFromIntAndMod( firstPrevRel, firstPrevRelMod ) );long firstNextRel = buffer.getUnsignedInt();long firstNextRelMod = (typeInt & 0x1C00000L) << 10;record.setFirstNextRel( longFromIntAndMod( firstNextRel, firstNextRelMod ) );long secondPrevRel = buffer.getUnsignedInt();long secondPrevRelMod = (typeInt & 0x380000L) << 13;record.setSecondPrevRel( longFromIntAndMod( secondPrevRel, secondPrevRelMod ) );long secondNextRel = buffer.getUnsignedInt();long secondNextRelMod = (typeInt & 0x70000L) << 16;record.setSecondNextRel( longFromIntAndMod( secondNextRel, secondNextRelMod ) );long nextProp = buffer.getUnsignedInt();long nextPropMod = (inUseByte & 0xF0L) << 28;byte extraByte = buffer.get();record.setFirstInFirstChain( (extraByte & 0x1) != 0 );record.setFirstInSecondChain( (extraByte & 0x2) != 0 );record.setNextProp( longFromIntAndMod( nextProp, nextPropMod ) );return record;} | 
当Node的Relationship数量超过一个阀值时,neo4j 会对 Relationship 进行分组,以便提供性能。neo4j 中用来实现这一功能的类是 RelationshipGroupStore.
其对应的文件存储格式如下:
整个文件是有一个 RECORD_SIZE=20Bytes 的定长数组和一个字符串“RelationshipGroupStore v0.A.2”(文件类型描述TYPE_DESCRIPTOR和 neo4j 的 ALL_STORES_VERSION构成)。访问时,可以通过 id 作为数组的下标进行访问。数组下标为0的 record 前4 Bytes 保存Relationship分组的阀值。
RelationshipGroupStore 的record 的格式如下:
// [ , x] in use
// [ ,xxx ] high next id bits
// [ xxx, ] high firstOut bits
long inUseByte = buffer.get();
// [ , x] in use
// [ ,xxx ] high next id bits
// [ xxx, ] high firstOut bits
long inUseByte = buffer.get();
Graph database_neo4j 底层存储结构分析(7)
标签:
原文地址:http://www.cnblogs.com/gisblogs/p/4545772.html