0%

CMU15-445-FALL2022-PROJECT_0

1 介绍

此次project0项目是实现一个键值对存储,数据结构由写时复制的字典树构成。实现的键-值存储可以存储映射到任何类型值的字符串键。键的值存储在表示该键的最后一个字符的节点中(又称终端节点)。例如,考虑在trie中插入kv对("ab", 1)和("ac", "val")。

2 Task1:Copy-On-Write trie

  • 在本任务中,只需要修改trie .htrie .cpp来实现写时复制(copy-on-write) tree。在写即复制tree中,操作不会直接修改原始tree中的节点。相反,将为修改后的数据创建新节点,并为新修改的trie返回一个新根。写时复制(Copy-on-write)使我们能够在每次操作之后随时以最小的开销访问该树。考虑在上面的例子中插入("ad", 2)。我们通过重用原始树中的两个子节点来创建一个新的Node2,并创建一个新的值节点2。(见下图)

  • 插入("b", 3),我们将创建一个新的根,一个新的节点,并重用以前的节点。通过这种方式,我们可以在每次插入操作之前和之后获得树的内容。只要我们有根对象(Trie类),我们就可以访问当时Trie中的数据。(见下图)

  • 插入(“a”,“abc”)并删除(“ab”,1),我们可以得到下面的trie。注意,父节点可以有值,并且在删除后需要清除所有不必要的节点。

因此,在这里你需要实现三个函数:

  • Get(key):获取键对应的值。

  • Put(key, value):设置键对应的值。如果键已经存在,则覆盖现有值。注意,值的类型可能是不可复制的(即std::unique_ptr<int>)。这个方法返回一个新的树。

  • Delete(key):删除键的值。这个方法返回一个新的树。

这些操作都不应该直接在trie本身上执行。您应该创建新的树节点,并尽可能重用现有的树节点。 要创建一个新节点,您应该使用TrieNode类上的Clone函数。要重用新树中的现有节点,可以复制std::shared_pt<TrieNode>复制共享指针不会复制底层数据。您不应该在此项目中通过使用newdelete手动分配内存。当没有人有对底层对象的引用时,std::shared_ptr将释放对象。

分析:

  • 节点类TrieNode使用map<char, std::shared_ptr<const TrieNode>>来存储这种键值结构,,在这里另一个重要的函数是Clone函数(使用了C++类的构造函数的隐式转换),Clone函数实现新建树中现有节点
  • 叶子类TrieNodeWithValue,继承于TrieNode,增加了叶子节点存值功能
  • Trie类,内部声明了root(初始为NULL),三个上述待实现的功能