std::atomic<bool> locked_;
};
+// We want to prevent false sharing
+template <class T>
+struct ALIGN_AS(CACHE_LINE_SIZE) LockData {
+ T lock_;
+};
+
+//
+// Inspired by Guava: https://github.com/google/guava/wiki/StripedExplained
+// A striped Lock. This offers the underlying lock striping similar
+// to that of ConcurrentHashMap in a reusable form, and extends it for
+// semaphores and read-write locks. Conceptually, lock striping is the technique
+// of dividing a lock into many <i>stripes</i>, increasing the granularity of a
+// single lock and allowing independent operations to lock different stripes and
+// proceed concurrently, instead of creating contention for a single lock.
+//
+template <class T, class P>
+class Striped {
+ public:
+ Striped(size_t stripes, std::function<uint64_t(const P &)> hash)
+ : stripes_(stripes), hash_(hash) {
+
+ locks_ = reinterpret_cast<LockData<T> *>(
+ port::cacheline_aligned_alloc(sizeof(LockData<T>) * stripes));
+ for (size_t i = 0; i < stripes; i++) {
+ new (&locks_[i]) LockData<T>();
+ }
+
+ }
+
+ virtual ~Striped() {
+ if (locks_ != nullptr) {
+ assert(stripes_ > 0);
+ for (size_t i = 0; i < stripes_; i++) {
+ locks_[i].~LockData<T>();
+ }
+ port::cacheline_aligned_free(locks_);
+ }
+ }
+
+ T *get(const P &key) {
+ uint64_t h = hash_(key);
+ size_t index = h % stripes_;
+ return &reinterpret_cast<LockData<T> *>(&locks_[index])->lock_;
+ }
+
+ private:
+ size_t stripes_;
+ LockData<T> *locks_;
+ std::function<uint64_t(const P &)> hash_;
+};
+
} // namespace ROCKSDB_NAMESPACE