# Linux 下表的实现与应用
### **总体要求:**
在 Linux 环境下,采用 C 或 C++,存储一张表,然后能对该表进行查询、添加等操作。上述功能以 API 的形式提供给应用使用。
### 存储要求:
利用文件操作 API,在文件系统中存储一张表。该表有 100 个属性,每个属性都是 8 字节大小。需要支持的最大行数为一百万行(可看作支持行数没有上限限制)。
### 添加要求:
提供 API 函数,实现向表格添加一行的功能(添加到表格的末尾)。
### 搜索要求:
提供 API 函数,实现对表格某一个属性进行范围查找或精确查找的功能。例如:查找在属性 A 上,大于等于 50,小于等于 100 的所有行,当上下限相等时,即为精确查找。
用户可以指定在哪一个属性上进行搜索。当搜索结果过多时,可以返回一小部分,如 10 行。
### 索引要求:
提供 API 函数,为表格里的某一个属性建立索引结构,以实现快速搜索。
自行选择使用哪种数据结构,建立索引结构,比如 B+ 树等。
建立的索引结构,需要保存到一个文件中(索引文件),下次重启应用程序,并执行搜索任务时,应先检查是否已为相应属性建立了索引结构。即,搜索功能实现时,需要查找是否有索引文件存在,若有,则使用该文件加速搜索。
### 并发要求:
应用程序可以以多线程的方式,使用上述 API。
要保证多线程环境下,表、索引结构、索引文件的一致性(考虑互斥的要求)。
### 测试要求:
表中的数据随机生成。
测试用例要覆盖主要的需求。
# 一、总体设计
**程序总体架构**
图 2-1 程序总体架构
图 2-1 所示是程序的总体架构。可以看到,在本次实验中,首先是完善表的基本结构和功能。其中记录的存储与读取,索引结构的构造,索引文件的存储与读取,是最先完善的。接着实现表的查询和添加功能。除此之外,为了使用的方便性,
本实验封装了两个 API 供外部程序使用。第一个是将表的查询和添加进行封装,外部程序可直接调用;考虑到多线程的环境,又封装了创建线程的 API,调用该
API 可以创建用于查询和添加的线程,实现并发,提高了效率。
**关键流程分析**
在本次实验中,为了提高查询速度,查询功能是基于索引结构的,而添加记录会引起索引结构的更新,因此,索引结构的实现是关键。本次实验选择了
B+ 树作为表的索引结构,执行查询功能时,会先检查索引文件是否存在,若不存在则创建索引结构进行查询,并将索引结构保存到索引文件中,供下次查询使用;若存在索引文件,则从中读取出索引结构进行查询。
为了实现并发功能,本实验封装了创建线程的 API,用于创建查询线程和添加线程,通过调用操作表格的 API,执行相应的功能。由于在多线程环境下,表格属于共享资源,因此必须考虑到互斥的要求,保证索引文件和表格中记录的一致性。
# 二、详细设计与实现
基本的数据结构
在本实验中,每条记录有 100 个属性,为了区分开每条记录,将其在文件中的序号作为主键,如下所示:
![](https://www.writebug.com/myres/static/uploads/2021/12/30/3a20b87a15c5114c184f1f682368cd0e.writebug)
构建某一属性的索引结构时,需要把所有记录的该属性值作为关键字构建 B+ 树,并将记录的序号一同保存,便于寻找该条记录。因此,B+ 树中的关键字定义如下:
![](https://www.writebug.com/myres/static/uploads/2021/12/30/ccb251782904e993fdfce418f1946df1.writebug)
为了提高查询效率,本实验选择构建四阶 B+ 树作为记录属性的索引,树节点定义如下:
![](https://www.writebug.com/myres/static/uploads/2021/12/30/c12c24e52f13e2498a68f9b980bb1ec3.writebug)
B+ 树的实现
![](https://www.writebug.com/myres/static/uploads/2021/12/30/ebe7f4743e185a0d474cbca7ef451fa1.writebug)
上面的代码为 B+ 树构建了一个类,里面是各种成员函数,包括构建一棵 B+ 树所需的一些基本函数,以及实现查询、插入、保存、读取的函数,下面依次展示它们的实现。
B+ 树的插入:
![](https://www.writebug.com/myres/static/uploads/2021/12/30/752b6a4cba5fa62074241ea9ea3ae540.writebug)
如上述代码所示,插入一条记录时,我们首先为其构建关键字结构。由于插入一个关键字有时会引起 B+ 树节点的分裂,所以我们在插入之前首先应检查当前节点关键字是否已满,如果已满,应先调BPlusTree_Split_Child 函数将其分裂成两个节点,然后再进行插入,以保证每次插入时当前节点都处于非满状态,此时调用 BPlusTree_Insert_NotFull 函数,插入该未满节点中。节点分裂的实现:
![](https://www.writebug.com/myres/static/uploads/2021/12/30/f0524b9f6452857f0f49e4a98d88e79d.writebug)
上述函数有三个参数,第一个是待分裂节点的父节点指针,第二个是分裂的位置,第三个是待分裂节点的指针。首先创建一个新的节点,将待分裂节点的后 M-1 个关键码和后 M 个孩子指针放入新建的节点,更新节点的成员值,并将待分裂节点最中间的关键码放入父节点,并调整父节点的孩子指针,使其指向正确的子节点。上述代码保证了每次分裂节点时,待分裂节点的父节点都处于非满状态,因此不会引起二次分裂。插入非满节点:
![](https://www.writebug.com/myres/static/uploads/2021/12/30/006c2eb702cbfe428f4a57dfc9b10adb.writebug)
需要判断该节点是否为叶节点,若是则直接插入相应位置,若不是,则根据节点中的关键字判断应插入的子节点,同样的,为了避免二次分裂,我们在插入子节点时,都应先判断子节点是否已满,然后递归地调用此函数,最终将关键字插入叶节点中。
B+ 树的插入采取的是先检查再插入的策略,而不是先插入再判断的策略,这样做的好处是避免了二次分裂,无需考虑子节点分裂后引起父节点分裂的情形。
B+ 树的搜索:
根据设计需求,既要实现精确查找,也要实现范围查找,编写相应函数分别实现这两个功能。由上述代码可知,构建出来的 B+ 树的所有叶节点从左到右形成了一个链表,且叶节点中的关键字从小到大排列,因此查询时先找到对应的叶节点,然后再顺着叶节点的 next 指针寻找。精确查找:
![](https://www.writebug.com/myres/static/uploads/2021/12/30/31c2cb391e23df38d3034e560b6db082.writebug)
精确查找的思路是:从根节点开始,从关键字数组的左端开始跟待查的关键字比较,遇到大于或者等于的关键字便停止,进入对应的子节点,重复该过程,直到到达叶节点,这样做是为了保证能够到达待查关键字可能出现的第一个叶节点,不会出现遗漏的情况。到达叶节点后,一直向右查找,保存与待查属性值相等的关键字的序号,遇到更大的属性值便停止,返回记录的序号数组。
范围查找:
![](https://www.writebug.com/myres/static/uploads/2021/12/30/007259e07c0da5a17ca705cd2412f8c8.writebug)
与精确查找类似,查找某个范围时,从左端和右端分别查找到叶节点,然后再从左端叶节点向右边逼近,保存搜索到的所有符合条件的记录。
B+ 树的保存:
![](https://www.writebug.com/myres/static/uploads/2021/12/30/e0090158e16d31eb22479f4ccbc1327c.writebug)
利用文件操作 API,将 B+ 树的每个节点按照深度优先的顺序写到文件中。
B+ 树的读取:
![](https://www.writebug.com/myres/static/uploads/20
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
在 Linux 环境下,采用 C 或 C++,存储一张表,然后能对该表进行查询、添加等操作。上述功能以 API 的形式提供给应用使用。利用文件操作 API,在文件系统中存储一张表。该表有 100 个属性,每个属性都是 8 字节大小。需要支持的最大行数为一百万行(可看作支持行数没有上限限制)。
资源推荐
资源详情
资源评论
收起资源包目录
100012196-基于C++在 Linux 下表的实现与应用.zip (53个子文件)
linux
table.h 1KB
BPlusTree.h 1KB
CLThread.h 437B
LICENSE 1KB
main.cpp 609B
BPlusTree.cpp 8KB
CLExecutiveFunctionInsert.h 460B
table.cpp 6KB
CLExecutiveFunctionProvider.h 360B
CLThread.cpp 821B
CLExecutive.h 487B
202021080306张浩 .pdf 1.13MB
img.doc-md
15-5182987fb3fa1cfb1d411b636af80b9f.png 14KB
38-35728b8d1c1ab2570cc026417a7a5714.png 125KB
4-e506b6cdeeb2d44d1c32d36dba83d707.png 113KB
33-2a3671f50515fa563ba03d54dd56abe8.png 11KB
2-cd36dd92cf44f3dd50097d7329265b3b.png 15KB
10-019aa095f196f9b4d5d7601533e28c6b.png 51KB
5-7cda3a44a0afe9c5c1fe474aac452f45.png 57KB
14-0cdc2a48aaede74545ba590cff7199d9.png 40KB
3-37bb996893236ba6615aed9f3b072bdd.png 36KB
26-359a341d34bd3d94ec9170db0b5476da.png 93KB
36-874111b5637091181e519c6eb9550f2f.png 69KB
23-793a0e5f4815e39a80ba5e9813591ee4.png 11KB
12-599601c6e2e35b85b8f903da0de5ca40.png 96KB
11-2d52f05f4311dbf7634c78ca1ff7aed6.png 39KB
8-2145cd1b7d5f6dec69fc26deccbf819c.png 80KB
20-425fca6699193f39b03e759cdcb1e8c9.png 29KB
37-b8442e2d9fc55d6493910ab43b58b101.png 62KB
35-29faa5f8016a0f6b9bf4a241e7c591b7.png 13KB
24-930015920ebc645e27404c4e9de65602.png 34KB
28-ca4d86a3d2944ebd8f74f2f6b19278d2.png 14KB
9-5c40befd85a6a21d21cd4861cbd8ba04.png 113KB
16-5ed96005ba86d9349ece79a311be8d7b.png 50KB
32-e756b3b26073d61b459cdc13684ac1d9.png 104KB
21-1f9712269730a68996fa083dfa8bc519.png 15KB
7-a0c30e0274184014b4194bb72ce31276.png 71KB
29-af28acafecd34210d0eedbd238f56644.png 110KB
31-ca4d86a3d2944ebd8f74f2f6b19278d2.png 14KB
27-fa7d1e3292e0c04c36fd378aaef92a4c.png 19KB
1-b7de4595b7c93e6a29bd9b77e5e7e7b0.png 18KB
30-60f3645d094ff068e1bde846590c9d3e.png 3KB
25-04c597d7a92a03e579cbdcb01d83ab61.png 13KB
6-ab29cb2aaae11f0b1faa76ab08ed8407.png 104KB
17-b62bee02d14c0d2d41003b1089d425ae.png 106KB
34-d21f05aee6b411e92d80f45ecad3a997.png 30KB
13-b546cb388d2008f2f28ad74f1b49828f.png 66KB
19-7265be2bf961774670ad2db7670e7518.png 72KB
22-a999c21bf61392842d38a81c912097e2.png 23KB
18-1632999d976291a1f7a1329dcaa06df5.png 41KB
README.md 16KB
CLExecutiveFunctionSearch.h 645B
struct.h 900B
共 53 条
- 1
资源评论
神仙别闹
- 粉丝: 2704
- 资源: 7645
下载权益
C知道特权
VIP文章
课程特权
开通VIP
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功