forked from boostorg/unordered
documented concurrent/unordered interop
This commit is contained in:
committed by
Christian Mazakas
parent
6b6dde4f97
commit
bf4a5efd2d
@ -10,6 +10,8 @@
|
|||||||
|
|
||||||
* Added `[c]visit_while` operations to `boost::concurrent_map`,
|
* Added `[c]visit_while` operations to `boost::concurrent_map`,
|
||||||
with serial and parallel variants.
|
with serial and parallel variants.
|
||||||
|
* Added efficient move construction of `boost::unordered_flat_map` from
|
||||||
|
`boost::concurrent_flat_map` and vice versa.
|
||||||
|
|
||||||
== Release 1.83.0 - Major update
|
== Release 1.83.0 - Major update
|
||||||
|
|
||||||
|
@ -201,3 +201,29 @@ and the user need not take any special precaution, but overall performance may b
|
|||||||
Another blocking operation is _rehashing_, which happens explicitly via `rehash`/`reserve`
|
Another blocking operation is _rehashing_, which happens explicitly via `rehash`/`reserve`
|
||||||
or during insertion when the table's load hits `max_load()`. As with non-concurrent containers,
|
or during insertion when the table's load hits `max_load()`. As with non-concurrent containers,
|
||||||
reserving space in advance of bulk insertions will generally speed up the process.
|
reserving space in advance of bulk insertions will generally speed up the process.
|
||||||
|
|
||||||
|
== Interoperability with non-concurrent containers
|
||||||
|
|
||||||
|
As their internal data structure is basically the same, `boost::unordered_flat_map` can
|
||||||
|
be efficiently move-constructed from `boost::concurrent_flat_map` and vice versa.
|
||||||
|
This interoperability comes handy in multistage scenarios where parts of the data processing happen
|
||||||
|
in parallel whereas other steps are non-concurrent (or non-modifying). In the following example,
|
||||||
|
we want to construct a histogram from a huge input vector of words:
|
||||||
|
the population phase can be done in parallel with `boost::concurrent_flat_map` and results
|
||||||
|
then transferred to the final container.
|
||||||
|
|
||||||
|
[source,c++]
|
||||||
|
----
|
||||||
|
std::vector<std::string> words = ...;
|
||||||
|
|
||||||
|
// Insert words in parallel
|
||||||
|
boost::concurrent_flat_map<std::string_view, std::size_t> m0;
|
||||||
|
std::for_each(
|
||||||
|
std::execution::par, words.begin(), words.end(),
|
||||||
|
[&](const auto& word) {
|
||||||
|
m0.try_emplace_or_visit(word, 1, [](auto& x) { ++x.second; });
|
||||||
|
});
|
||||||
|
|
||||||
|
// Transfer to a regular unordered_flat_map
|
||||||
|
boost::unordered_flat_map m=std::move(m0);
|
||||||
|
----
|
||||||
|
@ -69,6 +69,7 @@ namespace boost {
|
|||||||
explicit xref:#concurrent_flat_map_allocator_constructor[concurrent_flat_map](const Allocator& a);
|
explicit xref:#concurrent_flat_map_allocator_constructor[concurrent_flat_map](const Allocator& a);
|
||||||
xref:#concurrent_flat_map_copy_constructor_with_allocator[concurrent_flat_map](const concurrent_flat_map& other, const Allocator& a);
|
xref:#concurrent_flat_map_copy_constructor_with_allocator[concurrent_flat_map](const concurrent_flat_map& other, const Allocator& a);
|
||||||
xref:#concurrent_flat_map_move_constructor_with_allocator[concurrent_flat_map](concurrent_flat_map&& other, const Allocator& a);
|
xref:#concurrent_flat_map_move_constructor_with_allocator[concurrent_flat_map](concurrent_flat_map&& other, const Allocator& a);
|
||||||
|
xref:#concurrent_flat_map_move_constructor_from_unordered_flat_map[concurrent_flat_map](unordered_flat_map<Key, T, Hash, Pred, Allocator>&& other);
|
||||||
xref:#concurrent_flat_map_initializer_list_constructor[concurrent_flat_map](std::initializer_list<value_type> il,
|
xref:#concurrent_flat_map_initializer_list_constructor[concurrent_flat_map](std::initializer_list<value_type> il,
|
||||||
size_type n = _implementation-defined_
|
size_type n = _implementation-defined_
|
||||||
const hasher& hf = hasher(),
|
const hasher& hf = hasher(),
|
||||||
@ -501,6 +502,21 @@ Concurrency:;; Blocking on `other`.
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
==== Move Constructor from unordered_flat_map
|
||||||
|
|
||||||
|
```c++
|
||||||
|
concurrent_flat_map(unordered_flat_map<Key, T, Hash, Pred, Allocator>&& other);
|
||||||
|
```
|
||||||
|
|
||||||
|
Move construction from a xref:#unordered_flat_map[`unordered_flat_map`].
|
||||||
|
The internal bucket array of `other` is transferred directly to the new container.
|
||||||
|
The hash function, predicate and allocator are moved-constructed from `other`.
|
||||||
|
|
||||||
|
[horizontal]
|
||||||
|
Complexity:;; O(`bucket_count()`)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
==== Initializer List Constructor
|
==== Initializer List Constructor
|
||||||
[source,c++,subs="+quotes"]
|
[source,c++,subs="+quotes"]
|
||||||
----
|
----
|
||||||
|
@ -77,6 +77,7 @@ namespace boost {
|
|||||||
explicit xref:#unordered_flat_map_allocator_constructor[unordered_flat_map](const Allocator& a);
|
explicit xref:#unordered_flat_map_allocator_constructor[unordered_flat_map](const Allocator& a);
|
||||||
xref:#unordered_flat_map_copy_constructor_with_allocator[unordered_flat_map](const unordered_flat_map& other, const Allocator& a);
|
xref:#unordered_flat_map_copy_constructor_with_allocator[unordered_flat_map](const unordered_flat_map& other, const Allocator& a);
|
||||||
xref:#unordered_flat_map_move_constructor_with_allocator[unordered_flat_map](unordered_flat_map&& other, const Allocator& a);
|
xref:#unordered_flat_map_move_constructor_with_allocator[unordered_flat_map](unordered_flat_map&& other, const Allocator& a);
|
||||||
|
xref:#unordered_flat_map_move_constructor_from_concurrent_flat_map[unordered_flat_map](concurrent_flat_map<Key, T, Hash, Pred, Allocator>&& other);
|
||||||
xref:#unordered_flat_map_initializer_list_constructor[unordered_flat_map](std::initializer_list<value_type> il,
|
xref:#unordered_flat_map_initializer_list_constructor[unordered_flat_map](std::initializer_list<value_type> il,
|
||||||
size_type n = _implementation-defined_
|
size_type n = _implementation-defined_
|
||||||
const hasher& hf = hasher(),
|
const hasher& hf = hasher(),
|
||||||
@ -472,6 +473,22 @@ from `other`, and the allocator is copy-constructed from `a`.
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
==== Move Constructor from concurrent_flat_map
|
||||||
|
|
||||||
|
```c++
|
||||||
|
unordered_flat_map(concurrent_flat_map<Key, T, Hash, Pred, Allocator>&& other);
|
||||||
|
```
|
||||||
|
|
||||||
|
Move construction from a xref:#concurrent_flat_map[`concurrent_flat_map`].
|
||||||
|
The internal bucket array of `other` is transferred directly to the new container.
|
||||||
|
The hash function, predicate and allocator are moved-constructed from `other`.
|
||||||
|
|
||||||
|
[horizontal]
|
||||||
|
Complexity:;; Constant time.
|
||||||
|
Concurrency:;; Blocking on `other`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
==== Initializer List Constructor
|
==== Initializer List Constructor
|
||||||
[source,c++,subs="+quotes"]
|
[source,c++,subs="+quotes"]
|
||||||
----
|
----
|
||||||
|
Reference in New Issue
Block a user