Advertisement
MystMe

Untitled

Apr 2nd, 2018
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.84 KB | None | 0 0
  1. #pragma once
  2.  
  3. #include <tpcc/stdlike/atomic.hpp>
  4. #include <tpcc/stdlike/condition_variable.hpp>
  5. #include <tpcc/stdlike/mutex.hpp>
  6.  
  7. #include <tpcc/support/compiler.hpp>
  8.  
  9. #include <algorithm>
  10. #include <forward_list>
  11. #include <functional>
  12. #include <shared_mutex>
  13. #include <vector>
  14. #include <utility>
  15.  
  16. namespace tpcc {
  17. namespace solutions {
  18.  
  19. ////////////////////////////////////////////////////////////////////////////////
  20.  
  21. // implement writer-priority rwlock
  22. class ReaderWriterLock {
  23.  public:
  24.   // reader section / shared ownership
  25.  
  26.   void lock_shared() {
  27.     std::unique_lock<std::mutex> lock (mutex_);
  28.     while(write_acquire_ > 0) {
  29.       cond_var_.wait(lock);
  30.     }
  31.     readers_++;
  32.   }
  33.  
  34.   void unlock_shared() {
  35.     std::unique_lock<std::mutex> lock (mutex_);
  36.     readers_--;
  37.     cond_var_.notify_all();
  38.   }
  39.  
  40.   // writer section / exclusive ownership
  41.  
  42.   void lock() {
  43.     std::unique_lock<std::mutex> lock (mutex_);
  44.     write_acquire_++;
  45.     while(readers_ > 0 || write_) {
  46.       cond_var_.wait(lock);
  47.     }
  48.     write_ = true;
  49.   }
  50.  
  51.   void unlock() {
  52.     std::unique_lock<std::mutex> lock (mutex_);
  53.     write_acquire_--;
  54.     write_ = false;
  55.     cond_var_.notify_all();
  56.   }
  57.  
  58.  private:
  59.    bool write_{false};
  60.    size_t write_acquire_{0};
  61.    size_t readers_{0};
  62.  
  63.    tpcc::mutex mutex_;
  64.    tpcc::condition_variable cond_var_;
  65. };
  66.  
  67. ////////////////////////////////////////////////////////////////////////////////
  68.  
  69. template <typename T, class HashFunction = std::hash<T>>
  70. class StripedHashSet {
  71.  private:
  72.   using RWLock = ReaderWriterLock;  // std::shared_timed_mutex
  73.  
  74.   using ReaderLocker = std::shared_lock<RWLock>;
  75.   using WriterLocker = std::unique_lock<RWLock>;
  76.  
  77.   using Bucket = std::forward_list<T>;
  78.   using Buckets = std::vector<Bucket>;
  79.  
  80.  public:
  81.   explicit StripedHashSet(const size_t concurrency_level = 4,
  82.                           const size_t growth_factor = 2,
  83.                           const double max_load_factor = 0.8)
  84.       : concurrency_level_(concurrency_level),
  85.         growth_factor_(growth_factor),
  86.         max_load_factor_(max_load_factor) {
  87.           table_.resize(concurrency_level);
  88.           locks_ = std::vector<RWLock>(concurrency_level);
  89.   }
  90.  
  91.   bool Insert(T element) {
  92.     UNUSED(element);
  93.     return false;  // not implemented
  94.   }
  95.  
  96.   bool Remove(const T& element) {
  97.     UNUSED(element);
  98.     return false;  // not implemented
  99.   }
  100.  
  101.   bool Contains(const T& element) const {
  102.     UNUSED(element);
  103.     return false;  // not implemented
  104.   }
  105.  
  106.   size_t GetSize() const {
  107.     return num_of_items_;
  108.   }
  109.  
  110.   size_t GetBucketCount() const {
  111.     //ReaderLocker(locks_[0]);
  112.     auto stripe_lock = LockStripe<ReaderLocker> (0);
  113.     return table_.size();  // to be implemented
  114.   }
  115.  
  116.  private:
  117.   size_t GetStripeIndex(const size_t hash_value) const {
  118.     return GetBucketIndex(hash_value) % concurrency_level_;
  119.   }
  120.  
  121.   // use: auto stripe_lock = LockStripe<ReaderLocker>(hash_value);
  122.   template <class Locker>
  123.   Locker LockStripe(const size_t index) const {
  124.     return Locker(locks_[index]);
  125.   }
  126.  
  127.   size_t GetBucketIndex(const size_t hash_value) const {
  128.     return HashFunction(hash_value) % table_.size();
  129.   }
  130.  
  131.   Bucket& GetBucket(const size_t hash_value) {
  132.     return table_[GetBucketIndex(hash_value)];
  133.   }
  134.  
  135.   const Bucket& GetBucket(const size_t hash_value) const {
  136.     return table_[GetBucketIndex(hash_value)];
  137.   }
  138.  
  139.   bool MaxLoadFactorExceeded() const {
  140.     if (num_of_items_/table_.size() >= growth_factor_) {
  141.         return true;
  142.     }
  143.     return false;
  144.   }
  145.  
  146.   void TryExpandTable(const size_t expected_bucket_count) {
  147.     return;
  148.   }
  149.  
  150.  private:
  151.   size_t concurrency_level_;
  152.   size_t growth_factor_;
  153.   double max_load_factor_;
  154.  
  155.   size_t num_of_items_;
  156.   std::vector<RWLock> locks_;
  157.   Buckets table_;
  158. };
  159.  
  160. }  // namespace solutions
  161. }  // namespace tpcc
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement