blob: c3677e91b3cf003e3d6fde94903a759fed5c589b [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#ifndef GEODE_UTIL_SYNCHRONIZED_MAP_H_
#define GEODE_UTIL_SYNCHRONIZED_MAP_H_
#include <mutex>
#include <utility>
namespace apache {
namespace geode {
namespace client {
/**
* Wrapper around std::map, std::unordered_map and other map like
* implementations.
*
* This is a very incomplete implementation. Add methods as needed.
*
* @tparam Map type to wrap.
* @tparam Mutex type to synchronize with. Defaults to std::recursive_mutex
*/
template <class Map, class Mutex = std::recursive_mutex>
class synchronized_map {
private:
Map map_;
mutable Mutex mutex_;
public:
typedef Mutex mutex_type;
typedef Map map_type;
typedef typename Map::key_type key_type;
typedef typename Map::mapped_type mapped_type;
typedef typename Map::allocator_type allocator_type;
typedef typename Map::value_type value_type;
typedef typename Map::reference reference;
typedef typename Map::const_reference const_reference;
typedef typename Map::iterator iterator;
typedef typename Map::const_iterator const_iterator;
typedef typename Map::difference_type difference_type;
typedef typename Map::size_type size_type;
inline mutex_type& mutex() const noexcept { return mutex_; }
inline map_type& map() noexcept { return map_; }
inline const map_type& map() const noexcept { return map_; }
/**
* Allocates a Lock object around the Mutex and locks the Mutex.
*
* Example:
* \code{.cpp}
* auto&& guard = exampleMap.make_lock();
* \endcode
*
* Equivalent to:
* \code{.cpp}
* std::lock_guard<decltype(exampleMap)::mutex_type> guard(exampleMap.mutex);
* \endcode
*
* @tparam Lock type to allocate. Defaults to std::lock_guard.
* @return allocated Lock object with lock taken.
* @throws Any exception throws by Mutex::lock()
*/
template <template <class...> class Lock = std::lock_guard>
inline Lock<Mutex> make_lock() const {
mutex_.lock();
return {mutex_, std::adopt_lock};
}
/**
* Allocates a Lock object around the Mutex passing any args to the Lock
* constructor.
*
* Example:
* \code{.cpp}
* auto&& guard = exampleMap.make_lock<std::unique_lock>(std::defer_lock);
* \endcode
*
* Equivalent to:
* \code{.cpp}
* std::unique_lock<decltype(exampleMap)::mutex_type> guard(exampleMap.mutex,
* std::defer_lock); \endcode
*
* @tparam Lock type to allocate. Defaults to std::lock_guard.
* @tparam Args types passed to Lock constructor.
* @param args values passed to Lock constructor.
* @return allocated Lock object.
* @throws Any exception throws by Lock constructors.
*/
template <template <class...> class Lock = std::lock_guard, class... Args>
inline Lock<Mutex> make_lock(Args&&... args) const {
return {mutex_, std::forward<Args>(args)...};
}
template <class... Args>
inline std::pair<typename Map::iterator, bool> emplace(Args&&... args) {
std::lock_guard<Mutex> lock(mutex_);
return map_.emplace(std::forward<Args>(args)...);
}
inline size_type erase(const key_type& key) {
std::lock_guard<Mutex> lock(mutex_);
return map_.erase(key);
}
inline bool empty() const noexcept {
std::lock_guard<Mutex> lock(mutex_);
return map_.empty();
}
inline size_type size() const noexcept {
std::lock_guard<Mutex> lock(mutex_);
return map_.size();
}
inline void clear() noexcept {
std::lock_guard<Mutex> lock(mutex_);
map_.clear();
}
inline iterator find(const key_type& key) {
// std::lock_guard<Mutex> lock(mutex_);
return map_.find(key);
}
inline const_iterator find(const key_type& key) const {
// std::lock_guard<Mutex> lock(mutex_);
return map_.find(key);
}
inline iterator begin() noexcept { return map_.begin(); }
inline iterator end() noexcept { return map_.end(); }
inline const_iterator begin() const noexcept { return map_.begin(); }
inline const_iterator end() const noexcept { return map_.end(); }
inline const_iterator cbegin() const noexcept { return map_.begin(); }
inline const_iterator cend() const noexcept { return map_.end(); }
template <class InputIterator>
inline void insert(InputIterator first, InputIterator last) {
std::lock_guard<Mutex> lock(mutex_);
map_.insert(first, last);
}
};
} // namespace client
} // namespace geode
} // namespace apache
#endif // GEODE_UTIL_SYNCHRONIZED_MAP_H_