【CMU15-445数据库】bustub Project #0:Trie 树实现(C++ Primer)

这篇具有很好参考价值的文章主要介绍了【CMU15-445数据库】bustub Project #0:Trie 树实现(C++ Primer)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

第 0 个 Project 名为 C++ Primer,目标是实现一个字典树(Trie),内容不难,主要是测试参与者的 Modern C++ 编程水平,对于选课的 CMU 学生如果感觉比较吃力可能就要劝退了。

Project 说明:Project #0 - C++ Primer

本节要实现的内容全部在 src/include/primer/p0_trie.h 文件中。

字典树(Trie)是一种有序的树形结构,能够存储键值对并高效地进行前缀匹配,详细介绍可以自行百度。例如插入两个键值对 ("ab", 1)("ac", "val"),则形成下图的结构:
【CMU15-445数据库】bustub Project #0:Trie 树实现(C++ Primer)

root 是根节点,不存储键;a 是一个非终结节点,只存储键;下层的两个节点是终结节点,除了键还要存储一个任意类型的值。每个节点有一个 map 存储以每个子节点的键索引的子节点。本节相应做出了如下设计:
【CMU15-445数据库】bustub Project #0:Trie 树实现(C++ Primer)
TrieNode 表示非终结节点,成员为键,是否是终结节点的标记,子节点 map。TrieNodeWithValue 继承前者,表示终结节点,带有一个 T 类型的 value。二者可以通过 TrieNode 类中 is_end_ 标识区分。Trie 类表示整个 Trie 树。

TrieNode 的子节点 map 存储的是子节点的智能指针 unique_ptr<TrieNode> 而非裸指针。

【CMU15-445数据库】bustub Project #0:Trie 树实现(C++ Primer)
注意:本节是在头文件中写代码,不要图方便写 using namespace std

TrieNode 实现

构造函数

需要注意的是移动构造函数(move constructor),由于 unique_ptr 表示独占性资源,没有拷贝构造函数,所以这里我们要用 std::movekey_char_is_end_ 是简单的内置类型(primitive type),没必要使用 move 构造。

如果不理解为什么 T&& 参数需要 move,可以参考 这个回答 或我之前的这篇博客《Effective Modern C++》学习笔记 - Item 23: 理解 std::move 和 std::forward。
【CMU15-445数据库】bustub Project #0:Trie 树实现(C++ Primer)

InsertChildNode() 和 GetChildNode()

注意因为 unique_ptr 是独占性指针不能拷贝,返回值是 unique_ptr 的指针。

【CMU15-445数据库】bustub Project #0:Trie 树实现(C++ Primer)
【CMU15-445数据库】bustub Project #0:Trie 树实现(C++ Primer)

TrieNodeWithValue

构造函数

先调用基类的构造函数,is_end_ 是基类成员不能放在初始化列表中,放在函数体中赋值即可。
【CMU15-445数据库】bustub Project #0:Trie 树实现(C++ Primer)

Trie

Trie 树的主类,这里要求实现的是增 Insert()、删 Remove()、查(GetValue) 三个函数。关于 lock_ 下面会说明。

Insert()

沿 Trie 树搜索到键的最后一个字符,过程中如果节点不存在就创建。对于最后一个键的字符分三种情况:

  1. 如果相应节点不存在,创建一个终结节点 TrieNodeWithValue,插入成功;
  2. 如果相应节点存在但不是终结节点(通过 is_end_ 判断),将其转化为 TrieNodeWithValue 并把值赋给该节点,该操作不破坏以该键为前缀的后续其它节点(children_ 不变),插入成功;
  3. 如果相应节点存在且是终结节点,说明该键在 Trie 树存在,规定不能覆盖已存在的值,返回插入失败。

【CMU15-445数据库】bustub Project #0:Trie 树实现(C++ Primer)

Remove()

先沿 Trie 树逐字符向下搜索给定键,如果中途发现不存在直接返回 false。找到后,将该节点的 is_end_ 标为 false(此时虽然其值仍存在,但会被我们视为非终结节点)。如果该节点没有子节点,则可以删除。相应地还要向上回溯,如果其 parent 节点在移除该子节点后没有其它子节点,也删除。显然该函数可以有递归和非递归两种实现方式,我这里用非递归方式,在向下搜索时记录路径,回溯时反向遍历。因为使用智能指针,无需手动 delete 删除的 TrieNode

【CMU15-445数据库】bustub Project #0:Trie 树实现(C++ Primer)

GetValue()

沿 Trie 树查找,如果键不存在,或者节点中存储的值类型与函数调用的类型 T 不一致,将 *success 标识设为 false。类型判断的方式是使用 dynamic_cast

【CMU15-445数据库】bustub Project #0:Trie 树实现(C++ Primer)

并发访问(Concurrency)

要求 Trie 树能够并发访问,因此要加锁,具体也比较简单:GetValue() 时加读锁,Insert()Remove 时加写锁。项目已经提供了一个读写锁类 RWLatch,创建一个 private 成员 lock_ 放在 Trie 中,上面代码也展示了加锁解锁的操作。注意解锁要覆盖所有执行路径。

测试

test/primer/starter_trie_test.cpp 文件中 TEST() 包围的测试的名称的 DISABLED_ 前缀去除,然后编译并运行测试:

cd build
make starter_trie_test
./test/starter_trie_test

看到如下输出说明通过所有测试:

【CMU15-445数据库】bustub Project #0:Trie 树实现(C++ Primer)

运行代码格式化和规范检查:

make format
make check-lint
make check-clang-tidy-p0

必须改正所有提示,负责后续提交评分为 0。运行:

zip project0-submission.zip \
    src/include/primer/p0_trie.h 

生成压缩包,登录 GradeScope 并提交至 Project 0,得到以下结果则为完美通关~

【CMU15-445数据库】bustub Project #0:Trie 树实现(C++ Primer)文章来源地址https://www.toymoban.com/news/detail-441466.html

到了这里,关于【CMU15-445数据库】bustub Project #0:Trie 树实现(C++ Primer)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【CMU 15-445】Extendible Hash Table 可扩展哈希详细理解

    最近在学习CMU的15-445 DB课程,在做Project1的Extendible Hash Table的时候,由于是先看了课程,过了一个多星期才做的Lab,对extendible hash table只能说是知道大体的意思,并没有透彻的了解它,尤其是bucket指针和数据重分配这一部分,涉及到比较tricky的位运算,在一知半解的情况下实

    2024年02月09日
    浏览(34)
  • 大数据技术①|大数据第15章|HBase数据库与Cassandra数据库|18:00~18:15

    目录 15章习题 15.1 HBase 数据库有何基本功能?  15.2 Big Table 如何对稀疏数据进行存储的?  15.3 面向行的数据存储具有何特点?面向列的数据存储具有何特点?  15.4 HDFS 与 HBase 有何区别?  15.5 HBase 集群主要由哪几类节点构成?它们在集群中起到什么作用?  15.6 HBase 中的数

    2024年02月10日
    浏览(41)
  • CMU15445 (Spring 2023) #Project0

    写这篇文章,初衷是因为网上很少有关于CMU15445-2023的博客文章。记录下我在做的过程中走过的弯路,一方面是对自己工作的一个总结,另一方面也能帮助到在做这门课的 #project 时踩坑而无从下手的同学,何乐而不为? 我使用的编译环境: 系统:Ubuntu 20.04.1 IDE:Clion 语法要求

    2024年02月09日
    浏览(37)
  • 数据库工程师基础学习13,14,15----云计算,数据库主流应用技术,专利

    1,云计算与大数据处理 这里的是:按需访问,资源池模型.可用来申请服务器,网络等.无限扩展的存储. 这里公有云与私有云对应,一个面向大众,一个面向私人. 社区云,如学校网,只提供给特定组织使用. 这里主要是:云计算开发商提供的东西不同. 1)主要是基础设施提供 2)主要

    2024年02月05日
    浏览(41)
  • CentOS 7安装PostgreSQL 15版本数据库

    目录 一、何为PostgreSQL? 二、PostgreSQL安装 2.1安装依赖 2.2 执行安装 2.3 数据库初始化 2.4 配置环境变量 2.5 创建数据库 2.6 配置远程 2.7 测试远程 三、常用命令 四、用户创建和数据库权限 PostgreSQL是以加州大学伯克利分校计算机系开发的POSTGRES, 版本 4.2为基础的对象关系型数据

    2024年02月15日
    浏览(57)
  • Linux 源码安装: PostgreSQL 15.6数据库

    💖The Begin💖点点关注,收藏不迷路💖 🍒 PostgreSQL 中文文档 下载地址:https://www.postgresql.org/ftp/source/ 安装结果: vi ~/.bashrc ,如果全局的则编辑/etc/profile。 可以执行以下命令查看 PostgreSQL 版本信息: 1、创建一个名为 postgresql.service 的服务单元文件: 编辑 /etc/systemd/system/p

    2024年03月24日
    浏览(83)
  • 架构篇15:高性能数据库集群-分库分表

    上篇我们讲了“读写分离”,读写分离分散了数据库读写操作的压力,但没有分散存储压力,当数据量达到千万甚至上亿条的时候,单台数据库服务器的存储能力会成为系统的瓶颈,主要体现在这几个方面: 数据量太大,读写的性能会下降,即使有索引,索引也会变得很大,

    2024年01月24日
    浏览(44)
  • Docker环境安装Postgresql数据库Posrgresql 15.6

    宿主机是ubuntu 22.04版本 ubuntu宿主机上安装docker ,参见官方文档https://docs.docker.com/engine/install/ubuntu/, docker-ce是社区版 docker-ee是企业版 1、检查Docker是否安装 2、查看Docker各个版本,也可以参见https://download.docker.com/linux/ubuntu/dists/jammy/pool/stable/amd64/ 3、设置 Docker的apt仓库 4、安装

    2024年04月17日
    浏览(47)
  • Navicat15数据库导表及乱码问题解决

    Win10 PHPstudy_Pro(小皮) PHP5.6 MySQL5.7 1.启动Navicat15 2.点击连接按钮,并选择MySQL子项 3.连接对话框 连接名:自己分的清的名字即可 主机:数据的地址 若连接非本地mysql只需将主机localhost换成需要连接数据的ip地址即可,输入数据库用户名和数据库密码进行测试连接 端口:默认3306 用户名

    2024年02月01日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包