假设我有一个内存中的 b 树(不是 b+ 树),其节点声明如下:
struct node
{
int* keys;
struct node** children;
int currentNumOfKeys;
char isLeaf;
}
我读过使用
mmap()
,人们可以将内存区域映射到文件中并存储数据,忘记所有关于持久性的事情,并且下次加载程序时,所有指针都是有效的!假设您要么将文件映射到完全相同的起始地址,要么使用指针的相对偏移量!
现在,如果我想利用这一点,如何在映射区域内初始化结构对象?
通常,使用类似
struct node* root = (struct node*)malloc( sizeof(struct node) );
的东西会给我任意内存地址,无论操作系统需要什么。
我想要这样的东西:
1-初始化映射区域中树的第一个节点
2- 将我的更改为struct node** children
> 这样我就可以存储子节点从该根节点开始的偏移量int children[MAX_DEGREE]
3-初始化并存储映射区域中的下一个节点,以某种方式在下次程序启动时映射文件重新创建树而无需对其进行排序
struct node** children;
更改为 int children[MAX_DEGREE];
之类的内容,以存储每个子节点相对于根节点的相对偏移量。mmap 的问题是任何附加到共享内存的程序都可以看到它。
program1 shm program2
XXX
&XXX -> &XXX this is program1's &XXX
In program2, &xxx is different
解决这个问题的一种方法是使用带有索引的数组而不是指针。所以而不是
struct node
{
struct node* first_child;
struct node* next_node;
... some data;
};
使用类似的东西
struct node
{
unsigned short ix_next_node;
unsigned short ix_first_child;
... some data
};
如果需要向后导航,则需要前一个节点和父节点。假设节点不超过 65534 个。保留值 65535 表示没有节点。这样,children[MAX_DGREE] 就不是必需的,因为它实际上是一个单链表。所以如果树看起来像
+-- 0
| +-- 4
| | +-- 6
| | +-- 7
| |
| +-- 5
|
+-- 1
| +-- 2
|
+-- 3
父节点、上一个节点、下一个节点和子节点将是
Index parent prev next first
0 65535 65535 1 4
1 65535 0 3 65545
2 1 65545 65535 65535
3 65535 1 65535 65535
4 0 65535 5 65535
5 0 4 65535 65535
6 4 65535 7 65535
7 4 6 65535 65535
您现在需要做的就是编写一个程序来完成它。