Untitled

mail@pastecode.io avatar
unknown
c_cpp
a year ago
2.6 kB
1
Indexable
Never
#include "primer/trie_store.h"
#include "common/exception.h"

namespace bustub {

template <class T>
auto TrieStore::Get(std::string_view key) -> std::optional<ValueGuard<T>> {
  // Pseudo-code:
  // (1) Take the root lock, get the root, and release the root lock. Don't lookup the value in the
  //     trie while holding the root lock.
  // (2) Lookup the value in the trie.
  // (3) If the value is found, return a ValueGuard object that holds a reference to the value and the
  //     root. Otherwise, return std::nullopt.
  root_lock_.lock();
  auto trie_tmp = this->root_;
  root_lock_.unlock();

  auto node_value = trie_tmp.Get<T>(key);
  if (node_value != nullptr) {
    return ValueGuard(trie_tmp, *node_value);
  }

  return std::nullopt;
}

template <class T>
void TrieStore::Put(std::string_view key, T value) {
  // You will need to ensure there is only one writer at a time. Think of how you can achieve this.
  // The logic should be somehow similar to `TrieStore::Get`.

  write_lock_.lock();
  root_lock_.lock();
  auto trie_tmp = this->root_;
  root_lock_.unlock();

  auto trie_tmp2 = trie_tmp.Put(key, std::move(value));
  root_lock_.lock();
  this->root_ = trie_tmp2;
  root_lock_.unlock();

  write_lock_.unlock();
}

void TrieStore::Remove(std::string_view key) {
  // You will need to ensure there is only one writer at a time. Think of how you can achieve this.
  // The logic should be somehow similar to `TrieStore::Get`.
  write_lock_.lock();
  root_lock_.lock();
  auto trie_tmp = this->root_;
  root_lock_.unlock();

  auto trie_tmp2 = trie_tmp.Remove(key);
  root_lock_.lock();
  this->root_ = trie_tmp2;
  root_lock_.unlock();

  write_lock_.unlock();
}

// Below are explicit instantiation of template functions.

template auto TrieStore::Get(std::string_view key) -> std::optional<ValueGuard<uint32_t>>;
template void TrieStore::Put(std::string_view key, uint32_t value);

template auto TrieStore::Get(std::string_view key) -> std::optional<ValueGuard<std::string>>;
template void TrieStore::Put(std::string_view key, std::string value);

// If your solution cannot compile for non-copy tests, you can remove the below lines to get partial score.

using Integer = std::unique_ptr<uint32_t>;

template auto TrieStore::Get(std::string_view key) -> std::optional<ValueGuard<Integer>>;
template void TrieStore::Put(std::string_view key, Integer value);

template auto TrieStore::Get(std::string_view key) -> std::optional<ValueGuard<MoveBlocked>>;
template void TrieStore::Put(std::string_view key, MoveBlocked value);

}  // namespace bustub