39 #include <boost/align/aligned_allocator.hpp> 41 #include "mongo/stdx/mutex.h" 42 #include "mongo/util/assert_util.h" 43 #include "mongo/util/with_alignment.h" 47 inline std::size_t
partitionOf(
const char x,
const std::size_t nPartitions) {
48 return static_cast<unsigned char>(x) % nPartitions;
50 inline std::size_t
partitionOf(
const unsigned char x,
const std::size_t nPartitions) {
51 return x % nPartitions;
53 inline std::size_t
partitionOf(
const signed char x,
const std::size_t nPartitions) {
54 return static_cast<unsigned char>(x) % nPartitions;
56 inline std::size_t
partitionOf(
const int x,
const std::size_t nPartitions) {
57 return static_cast<unsigned int>(x) % nPartitions;
59 inline std::size_t
partitionOf(
const unsigned int x,
const std::size_t nPartitions) {
60 return x % nPartitions;
62 inline std::size_t
partitionOf(
const short x,
const std::size_t nPartitions) {
63 return static_cast<unsigned short>(x) % nPartitions;
65 inline std::size_t
partitionOf(
const unsigned short x,
const std::size_t nPartitions) {
66 return x % nPartitions;
68 inline std::size_t
partitionOf(
const long x,
const std::size_t nPartitions) {
69 return static_cast<unsigned long>(x) % nPartitions;
71 inline std::size_t
partitionOf(
const unsigned long x,
const std::size_t nPartitions) {
72 return x % nPartitions;
74 inline std::size_t
partitionOf(
const long long x,
const std::size_t nPartitions) {
75 return static_cast<unsigned long long>(x) % nPartitions;
77 inline std::size_t
partitionOf(
const unsigned long long x,
const std::size_t nPartitions) {
78 return x % nPartitions;
80 inline std::size_t
partitionOf(
const wchar_t x,
const std::size_t nPartitions) {
81 return x % nPartitions;
83 inline std::size_t
partitionOf(
const char16_t x,
const std::size_t nPartitions) {
84 return x % nPartitions;
86 inline std::size_t
partitionOf(
const char32_t x,
const std::size_t nPartitions) {
87 return x % nPartitions;
97 std::size_t
operator()(
const T& x,
const std::size_t nPartitions) {
102 namespace partitioned_detail {
106 template <
typename Key,
typename Value>
107 Key
getKey(
const std::pair<Key, Value>& pair) {
108 return std::get<0>(pair);
111 template <
typename Key>
116 template <
typename T>
118 std::vector<stdx::unique_lock<stdx::mutex>> result;
119 result.reserve(mutexes.size());
120 std::transform(mutexes.begin(), mutexes.end(), std::back_inserter(result), [](
auto&& mutex) {
121 return stdx::unique_lock<stdx::mutex>{mutex};
134 template <
typename AssociativeContainer,
135 std::size_t nPartitions = 16,
143 static_assert(nPartitions > 0,
"cannot create partitioned structure with 0 partitions");
144 using value_type =
typename AssociativeContainer::value_type;
145 using key_type =
typename AssociativeContainer::key_type;
160 : _lockGuards(partitioned_detail::
lockAllPartitions(partitionedContainer._mutexes)),
161 _partitionedContainer(&partitionedContainer) {}
168 return this->_partitionedContainer->_partitions.begin();
175 return this->_partitionedContainer->_partitions.end();
182 return this->_partitionedContainer->_partitions.begin();
184 void begin() && =
delete;
190 return this->_partitionedContainer->_partitions.end();
192 void end() && =
delete;
198 return std::accumulate(
199 this->_partitionedContainer->_partitions.begin(),
200 this->_partitionedContainer->_partitions.end(),
202 [](
auto&& total,
auto&& partition) {
return total + partition.size(); });
209 return std::all_of(this->_partitionedContainer->_partitions.begin(),
210 this->_partitionedContainer->_partitions.end(),
211 [](
auto&& partition) {
return partition.empty(); });
218 auto partitionId = KeyPartitioner()(
key, nPartitions);
219 return this->_partitionedContainer->_partitions[partitionId].count(key);
226 for (
auto&& partition : this->_partitionedContainer->_partitions) {
235 const auto partitionId =
237 this->_partitionedContainer->_partitions[partitionId].insert(std::move(value));
245 const auto partitionId = KeyPartitioner()(
key, nPartitions);
246 return this->_partitionedContainer->_partitions[partitionId].erase(
key);
248 void erase(
const key_type&) && =
delete;
268 return &this->_partitioned->_partitions[
_id];
270 void operator->() && =
delete;
276 return this->_partitioned->_partitions[
_id];
278 void operator*() && =
delete;
289 : _partitionLock(partitioned._mutexes[partitionId]),
290 _partitioned(&partitioned),
317 [](
auto&& partition) {
return partition.empty(); });
326 return std::accumulate(
330 [](
auto&& total,
auto&& partition) {
return total + partition.size(); });
338 auto partition = this->lockOnePartition(
key);
339 return partition->count(
key);
341 void count(
const key_type&) && =
delete;
356 auto partition = this->lockOnePartitionById(
358 partition->insert(std::move(value));
367 auto partition = this->lockOnePartition(
key);
368 return partition->erase(
key);
370 void erase(
const key_type&) && =
delete;
387 template <
typename T>
388 using AlignedVector = std::vector<T, boost::alignment::aligned_allocator<T>>;
auto begin() &
Returns an iterator at the start of the partitions.
Definition: partitioned.h:167
stdx::unique_lock< stdx::mutex > _partitionLock
Definition: partitioned.h:293
std::size_t size() const
Returns the number of elements in all partitions, summed together.
Definition: partitioned.h:197
Copyright (C) 2014 MongoDB Inc.
Definition: bson_collection_catalog_entry.cpp:38
typename AssociativeContainer::value_type value_type
Definition: partitioned.h:144
The default partitioning policy: If using a numeric built-in type, will use the lower bits of a numbe...
Definition: partitioned.h:96
BSONObj key
Definition: btree_interface.cpp:334
Key getKey(const Key &key)
Definition: partitioned.h:112
OnePartition lockOnePartitionById(PartitionId id) &
Definition: partitioned.h:380
std::size_t partitionOf(const char x, const std::size_t nPartitions)
Definition: partitioned.h:47
void clear()
Empties each container within each partition.
Definition: partitioned.h:225
std::vector< stdx::unique_lock< stdx::mutex > > _lockGuards
Definition: partitioned.h:253
OnePartition(Partitioned &partitioned, PartitionId partitionId)
Acquires locks for the ith partition.
Definition: partitioned.h:288
typename AssociativeContainer::key_type key_type
Definition: partitioned.h:145
Used to protect access to all partitions of this partitioned associative structure.
Definition: partitioned.h:153
auto begin() const &
Returns an iterator at the start of the partitions.
Definition: partitioned.h:181
void clear()
Empties all partitions.
Definition: partitioned.h:346
AssociativeContainer * operator->() const &
Returns a pointer to the structure in this partition.
Definition: partitioned.h:267
CacheAligned< stdx::mutex > CacheAlignedMutex
Definition: partitioned.h:104
std::vector< T, boost::alignment::aligned_allocator< T > > AlignedVector
Definition: partitioned.h:388
Partitioned * _partitionedContainer
Definition: partitioned.h:254
RecordId _id
Definition: wiredtiger_index.cpp:1132
AlignedLockStats _partitions[NumPartitions]
Definition: lock_state.cpp:103
Partitioned * _partitioned
Definition: partitioned.h:294
All lockAllPartitions() &
Definition: partitioned.h:372
AlignedVector< CacheAlignedAssociativeContainer > _partitions
Definition: partitioned.h:393
A templated class used to partition an associative container like a set or a map to increase scalabil...
Definition: partitioned.h:137
std::size_t erase(const key_type &key) &
Erases one entry from the partitioned structure, returns the number of entries removed.
Definition: partitioned.h:244
std::vector< stdx::unique_lock< stdx::mutex > > lockAllPartitions(T &mutexes)
Definition: partitioned.h:117
PartitionId _id
Definition: partitioned.h:295
auto end() const &
Returns an iterator at the end of the partitions.
Definition: partitioned.h:189
CacheAligned< AssociativeContainer > CacheAlignedAssociativeContainer
Definition: partitioned.h:385
AlignedVector< partitioned_detail::CacheAlignedMutex > _mutexes
Definition: partitioned.h:392
std::size_t count(const key_type &key) &
Returns the number of entries with the given key.
Definition: partitioned.h:337
All(Partitioned &partitionedContainer)
Acquires locks for all partitions.
Definition: partitioned.h:159
void insert(const value_type value) &
Inserts a single value into the partitioned structure.
Definition: partitioned.h:355
Definition: partitioned.h:140
auto end() &
Returns an iterator at the end of the partitions.
Definition: partitioned.h:174
std::size_t operator()(const T &x, const std::size_t nPartitions)
Definition: partitioned.h:97
Used to protect access to a single partition of a Partitioned.
Definition: partitioned.h:262
std::size_t size() const
Returns the number of elements in all partitions, summed together.
Definition: partitioned.h:324
std::size_t count(const key_type &key) const
Returns the number of entries with the given key.
Definition: partitioned.h:217
void insert(value_type value) &
Inserts value into its designated partition.
Definition: partitioned.h:234
OnePartition lockOnePartition(const key_type key) &
Definition: partitioned.h:376
Partitioned()
Constructs a partitioned version of a AssociativeContainer, with nPartitions partitions.
Definition: partitioned.h:301
bool empty() const
Returns true if each partition is empty.
Definition: partitioned.h:208
Key getKey(const std::pair< Key, Value > &pair)
Definition: partitioned.h:107
std::size_t erase(const key_type &key) &
Erases one entry from the partitioned structure.
Definition: partitioned.h:366
std::size_t PartitionId
Definition: partitioned.h:146
bool empty() const
Returns true if each partition is empty.
Definition: partitioned.h:313
AssociativeContainer & operator*() const &
Returns a reference to the structure in this partition.
Definition: partitioned.h:275