1 overview
在RedisGraph的整体架构中,非常简略的概括了RedisGraph的图存储模型:
- RedisGraph使用DataBlock来存储node和edge的属性。
- RedisGraph使用稀疏矩阵来表示图,稀疏矩阵的存储格式为按行压缩的稀疏矩阵(Compressed Sparse Row Matrix, CSR_Matrix)。
DataBlock是如何存储node和edge的属性的?使用稀疏矩阵表示图的具体设计有哪些?本文关注RedisGraph的图存储模型。
2 DataBlock
DataBlock是一种容器数据结构,用于存储同一类型的item。简单理解,DataBlock是一种数组,可以根据index对Block进行查询,只不过是,这个数组设计比较复杂,需要支持高效率的增删查改以及resize操作。
在RedisGraph中,DataBlock的用途之一是存储node和edge的属性(key-value键值对)。
2.1 the implement of DataBlock
首先,我们看一下DataBlock这个数据结构的定义:
typedef struct {
	uint64_t itemCount;         // Number of items stored in datablock.
	uint64_t itemCap;           // Number of items datablock can hold.
	uint64_t blockCap;          // Number of items a single block can hold.
	uint blockCount;            // Number of blocks in datablock.
	uint itemSize;              // Size of a single item in bytes.
	Block **blocks;             // Array of blocks.
	uint64_t *deletedIdx;       // Array of free indicies.
	fpDestructor destructor;    // Function pointer to a clean-up function of an item.
} DataBlock;
typedef struct Block {
	size_t itemSize;        // Size of a single item in bytes.
	struct Block *next;     // Pointer to next block.
	unsigned char data[];   // Item array. MUST BE LAST MEMBER OF THE STRUCT!
} Block;
- 一个包含16个item、4个Block的的DataBlock如下图所示:

-  DataBlock要求每一个item的size相同,一般只存储同一种类型的item。 
-  每一个item的第一个bit,用于表示item是否被删除,itemSize = sizeof(item)+1。 
-  blockCount 表示为block的数量。blockCount = itemCap/blockCap。 
-  当DataBlock的容量不足的时候,就会对DataBlock扩容,增加一个Block。此时,会 realloc()blocks数组,将新增的Block指针加到blocks数组末尾。仅支持扩容,不支持缩容。
-  deletedIdx是一个队列,用于暂时存放被释放的item的index。当需要分配新的item的空间时,则优先从deletedIdx取空闲的item的index。 
-  Block中存在指向下一个Block的指针。目的是,方便对DataBlock进行遍历操作。 
-  查询的时间复杂度为O(1)。 对于查询DataBlock中第idx个item: Block *block = idx / dataBlock->blockCap; idx = idx % dataBlock->blockCap; void* target_item = block->data + (idx * block->itemSize);
-  总的来说,DataBlock是一个增删查改均十分高效的容器数据结构。 
2.2 DataBlock for graph store
#define NODE_CREATION_BUFFER_DEFAULT 16384
 未完待续



















