Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma once
- #include <tpcc/stdlike/atomic.hpp>
- #include <tpcc/stdlike/condition_variable.hpp>
- #include <tpcc/stdlike/mutex.hpp>
- #include <tpcc/support/compiler.hpp>
- #include <algorithm>
- #include <forward_list>
- #include <functional>
- #include <shared_mutex>
- #include <vector>
- #include <utility>
- namespace tpcc {
- namespace solutions {
- ////////////////////////////////////////////////////////////////////////////////
- // implement writer-priority rwlock
- class ReaderWriterLock {
- public:
- // reader section / shared ownership
- void lock_shared() {
- std::unique_lock<std::mutex> lock (mutex_);
- while(write_acquire_ > 0) {
- cond_var_.wait(lock);
- }
- readers_++;
- }
- void unlock_shared() {
- std::unique_lock<std::mutex> lock (mutex_);
- readers_--;
- cond_var_.notify_all();
- }
- // writer section / exclusive ownership
- void lock() {
- std::unique_lock<std::mutex> lock (mutex_);
- write_acquire_++;
- while(readers_ > 0 || write_) {
- cond_var_.wait(lock);
- }
- write_ = true;
- }
- void unlock() {
- std::unique_lock<std::mutex> lock (mutex_);
- write_acquire_--;
- write_ = false;
- cond_var_.notify_all();
- }
- private:
- bool write_{false};
- size_t write_acquire_{0};
- size_t readers_{0};
- tpcc::mutex mutex_;
- tpcc::condition_variable cond_var_;
- };
- ////////////////////////////////////////////////////////////////////////////////
- template <typename T, class HashFunction = std::hash<T>>
- class StripedHashSet {
- private:
- using RWLock = ReaderWriterLock; // std::shared_timed_mutex
- using ReaderLocker = std::shared_lock<RWLock>;
- using WriterLocker = std::unique_lock<RWLock>;
- using Bucket = std::forward_list<T>;
- using Buckets = std::vector<Bucket>;
- public:
- explicit StripedHashSet(const size_t concurrency_level = 4,
- const size_t growth_factor = 2,
- const double max_load_factor = 0.8)
- : concurrency_level_(concurrency_level),
- growth_factor_(growth_factor),
- max_load_factor_(max_load_factor) {
- table_.resize(concurrency_level);
- locks_ = std::vector<RWLock>(concurrency_level);
- }
- bool Insert(T element) {
- UNUSED(element);
- return false; // not implemented
- }
- bool Remove(const T& element) {
- UNUSED(element);
- return false; // not implemented
- }
- bool Contains(const T& element) const {
- UNUSED(element);
- return false; // not implemented
- }
- size_t GetSize() const {
- return num_of_items_;
- }
- size_t GetBucketCount() const {
- //ReaderLocker(locks_[0]);
- auto stripe_lock = LockStripe<ReaderLocker> (0);
- return table_.size(); // to be implemented
- }
- private:
- size_t GetStripeIndex(const size_t hash_value) const {
- return GetBucketIndex(hash_value) % concurrency_level_;
- }
- // use: auto stripe_lock = LockStripe<ReaderLocker>(hash_value);
- template <class Locker>
- Locker LockStripe(const size_t index) const {
- return Locker(locks_[index]);
- }
- size_t GetBucketIndex(const size_t hash_value) const {
- return HashFunction(hash_value) % table_.size();
- }
- Bucket& GetBucket(const size_t hash_value) {
- return table_[GetBucketIndex(hash_value)];
- }
- const Bucket& GetBucket(const size_t hash_value) const {
- return table_[GetBucketIndex(hash_value)];
- }
- bool MaxLoadFactorExceeded() const {
- if (num_of_items_/table_.size() >= growth_factor_) {
- return true;
- }
- return false;
- }
- void TryExpandTable(const size_t expected_bucket_count) {
- return;
- }
- private:
- size_t concurrency_level_;
- size_t growth_factor_;
- double max_load_factor_;
- size_t num_of_items_;
- std::vector<RWLock> locks_;
- Buckets table_;
- };
- } // namespace solutions
- } // namespace tpcc
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement