Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove useless memory allocation & string field in lock manager & guard #1637

Merged
merged 1 commit into from
Aug 6, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 23 additions & 29 deletions src/common/lock_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,24 +30,25 @@

class LockManager {
public:
explicit LockManager(unsigned hash_power) : hash_power_(hash_power), hash_mask_((1U << hash_power) - 1) {
mutex_pool_.reserve(Size());
for (unsigned i = 0; i < Size(); i++) {
mutex_pool_.emplace_back(new std::mutex{});
}
}
explicit LockManager(unsigned hash_power)
: hash_power_(hash_power), hash_mask_((1U << hash_power) - 1), mutex_pool_(Size()) {}
~LockManager() = default;

LockManager(const LockManager &) = delete;
LockManager &operator=(const LockManager &) = delete;

unsigned Size() const { return (1U << hash_power_); }

void Lock(std::string_view key) { mutex_pool_[hash(key)]->lock(); }
void UnLock(std::string_view key) { mutex_pool_[hash(key)]->unlock(); }
void Lock(std::string_view key) { mutex_pool_[hash(key)].lock(); }
void UnLock(std::string_view key) { mutex_pool_[hash(key)].unlock(); }
void Lock(rocksdb::Slice key) { Lock(key.ToStringView()); }
void UnLock(rocksdb::Slice key) { UnLock(key.ToStringView()); }

template <typename Key>
std::mutex *Get(const Key &key) {
return &mutex_pool_[hash(key)];
}

template <typename Keys>
std::vector<std::mutex *> MultiGet(const Keys &keys) {
std::set<unsigned, std::greater<unsigned>> to_acquire_indexes;
Expand All @@ -65,48 +66,42 @@ class LockManager {
std::vector<std::mutex *> locks;
locks.reserve(to_acquire_indexes.size());
for (auto index : to_acquire_indexes) {
locks.emplace_back(mutex_pool_[index].get());
locks.emplace_back(&mutex_pool_[index]);
}
return locks;
}

private:
unsigned hash_power_;
unsigned hash_mask_;
std::vector<std::unique_ptr<std::mutex>> mutex_pool_;
std::vector<std::mutex> mutex_pool_;

unsigned hash(std::string_view key) const { return std::hash<std::string_view>{}(key)&hash_mask_; }
};

template <typename KeyType>
class BasicLockGuard {
class LockGuard {
public:
explicit BasicLockGuard(LockManager *lock_mgr, KeyType key) : lock_mgr_(lock_mgr), key_(std::move(key)) {
lock_mgr->Lock(key_);
template <typename KeyType>
explicit LockGuard(LockManager *lock_mgr, const KeyType &key) : lock_(lock_mgr->Get(key)) {
lock_->lock();
}
~BasicLockGuard() {
if (lock_mgr_) lock_mgr_->UnLock(key_);
~LockGuard() {
if (lock_) lock_->unlock();
}

BasicLockGuard(const BasicLockGuard &) = delete;
BasicLockGuard &operator=(const BasicLockGuard &) = delete;
LockGuard(const LockGuard &) = delete;
LockGuard &operator=(const LockGuard &) = delete;

BasicLockGuard(BasicLockGuard &&guard) : lock_mgr_(guard.lock_mgr_), key_(std::move(guard.key_)) {
guard.lock_mgr_ = nullptr;
}
LockGuard(LockGuard &&guard) : lock_(guard.lock_) { guard.lock_ = nullptr; }

private:
LockManager *lock_mgr_ = nullptr;
KeyType key_;
std::mutex *lock_;
};

using LockGuard = BasicLockGuard<rocksdb::Slice>;

class MultiLockGuard {
public:
template <typename Keys>
explicit MultiLockGuard(LockManager *lock_mgr, const Keys &keys)
: lock_mgr_(lock_mgr), locks_(lock_mgr_->MultiGet(keys)) {
explicit MultiLockGuard(LockManager *lock_mgr, const Keys &keys) : locks_(lock_mgr->MultiGet(keys)) {
for (const auto &iter : locks_) {
iter->lock();
}
Expand All @@ -122,9 +117,8 @@ class MultiLockGuard {
MultiLockGuard(const MultiLockGuard &) = delete;
MultiLockGuard &operator=(const MultiLockGuard &) = delete;

MultiLockGuard(MultiLockGuard &&guard) : lock_mgr_(guard.lock_mgr_), locks_(std::move(guard.locks_)) {}
MultiLockGuard(MultiLockGuard &&guard) : locks_(std::move(guard.locks_)) {}

private:
LockManager *lock_mgr_ = nullptr;
std::vector<std::mutex *> locks_;
};