在C中的内存映射文件区域中定义变量以使用mmap存储内存树

问题描述 投票:0回答:1

背景:

假设我有一个内存中的 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-初始化并存储映射区域中的下一个节点,以某种方式在下次程序启动时映射文件重新创建树而无需对其进行排序


备注:

  1. 在每一步中,我都希望避免使用交换文件来弥补内存不足或将数据复制到磁盘中(除了映射的 文件明显)各种。
  2. 我会将
    struct node** children;
    更改为
    int children[MAX_DEGREE];
    之类的内容,以存储每个子节点相对于根节点的相对偏移量。

编辑问题以更加关注一个问题
c linux memory memory-management mmap
1个回答
0
投票

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

您现在需要做的就是编写一个程序来完成它。

© www.soinside.com 2019 - 2024. All rights reserved.