通关记录
本项目主要是实现一个支持并发读写的可持久化字典树和一个大小写转换功能。
对于的可持久化字典树,我们需要实现三个函数
template <class T>
auto Trie::Get(std::string_view key) const -> const T *
template <class T>
auto Trie::Put(std::string_view key, T value) const -> Trie
auto Trie::Remove(std::string_view key) const -> Trie
这里对于 Put 和 Remove 都是写了一个dfs的 lambda 函数来实现的,感觉非递归的写法有些丑。
对于后两个函数中节点的复制要使用 Clone 方法,因为可以不用考虑结点是否是带值的并且是课程要求!
接下来是完善 copy-on-write
template <class T>
auto TrieStore::Get(std::string_view key) -> std::optional<ValueGuard<T>>
template <class T>
void TrieStore::Put(std::string_view key, T value)
void TrieStore::Remove(std::string_view key)
这里使用 std::lock_guard<std::mutex> 锁来实现,主要思路是:
std::lock_guard<std::mutex> w_lock(write_lock_);
Trie new_trie = root_.Put<T>(key, std::move(value));
{
std::lock_guard<std::mutex> r_lock(root_lock_);
root_ = new_trie;
}
踩坑指南
GitHub 仓库上的是最新课程的,如果要完成以往的课程要回滚到相应的 commit ,不然就像自己 debug 半天怀疑人生
Mac 上的 clang-tidy 对于 GetFuncCallFromFactory 函数的 style 和课程要求的不一样,需要手动修改为下面的才不会爆零。
auto Planner::GetFuncCallFromFactory(const std::string &func_name, std::vector<AbstractExpressionRef> args)
-> AbstractExpressionRef {