Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
amdis
amdis-core
Commits
b356d05e
Commit
b356d05e
authored
Feb 01, 2019
by
Müller, Felix
Browse files
Added local (instance) storage option to ConcurrentCache
parent
32e77c49
Changes
2
Hide whitespace changes
Inline
Side-by-side
src/amdis/GridTransferManager.hpp
View file @
b356d05e
...
...
@@ -78,7 +78,8 @@ namespace AMDiS
static
GridTransferInterface
*
gridTransferInterface
(
Grid
const
&
grid
)
{
Key
key
=
Key
(
&
grid
);
auto
&
gridTransferInterfaceUniquePtr
=
GridTransferCache
::
get
(
key
,
[
&
](
Key
const
&
)
GridTransferCache
cache
;
auto
&
gridTransferInterfaceUniquePtr
=
cache
.
get
(
key
,
[
&
](
Key
const
&
)
{
return
std
::
make_unique
<
GridTransfer
<
Grid
>>
();
});
...
...
src/amdis/utility/ConcurrentCache.hpp
View file @
b356d05e
...
...
@@ -11,6 +11,10 @@
namespace
AMDiS
{
/// Store cache in instance.
template
<
class
Container
>
struct
ConsecutivePolicy
;
/// Store cache thread local, requires no locking.
template
<
class
Container
>
struct
ThreadLocalPolicy
;
...
...
@@ -29,9 +33,10 @@ namespace AMDiS
* \tparam Key The type of key to access the data.
* \tparam Data The type of the data stored in the cache. The behaviur is undefined if Data is not
* the same type as Container::mapped_type.
* \tparam Policy A policy class template implementing the method `get_or_init()`. Two implementations
* are provided: \ref ThreadLocalPolicy and \ref StaticLockedPolicy. By default, if not
* Policy class template is specified, the `ThreadLocalPolicy` is used. \see ConcurrentCachePolicy
* \tparam Policy A policy class template implementing the method `get_or_init()`. Three implementations
* are provided: \ref ConsecutivePolicy, \ref ThreadLocalPolicy and \ref StaticLockedPolicy.
* By default, if no policy class template is specified, the `ThreadLocalPolicy` is used.
* \see ConcurrentCachePolicy
* \tparam Container The type of the underlying associative container to use to store the data. The
* container must satisfy the requirements of AssociativeContainer. The standard
* containers `std::map` and `std::unordered_map` satisfie this requirement. By default,
...
...
@@ -54,7 +59,7 @@ namespace AMDiS
* Provide a static cache and a `get_or_init()` static method that extracts the data from the cache if it exists or
* creates a new extry by using an initialization functor.
*
* Realizations of this template are \ref ThreadLocalPolicy and \ref StaticLockedPolicy.
* Realizations of this template are \ref
ConsecutivePolicy, \ref
ThreadLocalPolicy and \ref StaticLockedPolicy.
*
* \tparam Container The Type of the associative container key->data to store the cached data.
**/
...
...
@@ -62,7 +67,54 @@ namespace AMDiS
class
ConcurrentCachePolicy
;
#endif
// implementation of the ThreadLocal policy
// implementation of the consecutive policy. Data is stored in instance variable.
template
<
class
Container
>
struct
ConsecutivePolicy
{
using
key_type
=
typename
Container
::
key_type
;
using
data_type
=
typename
Container
::
mapped_type
;
using
container_type
=
Container
;
template
<
class
F
,
class
...
Args
>
data_type
const
&
get_or_init
(
key_type
const
&
key
,
F
&&
f
,
Args
&&
...
args
)
const
{
return
impl
(
std
::
is_default_constructible
<
data_type
>
{},
key
,
std
::
forward
<
F
>
(
f
),
std
::
forward
<
Args
>
(
args
)...);
}
private:
// data_type is default_constructible
template
<
class
F
,
class
...
Args
>
data_type
const
&
impl
(
std
::
true_type
,
key_type
const
&
key
,
F
&&
f
,
Args
&&
...
args
)
const
{
data_type
empty
;
auto
it
=
cachedData_
.
emplace
(
key
,
std
::
move
(
empty
));
if
(
it
.
second
)
{
data_type
data
=
f
(
key
,
std
::
forward
<
Args
>
(
args
)...);
it
.
first
->
second
=
std
::
move
(
data
);
}
return
it
.
first
->
second
;
}
// data_type is not default_constructible
template
<
class
F
,
class
...
Args
>
data_type
const
&
impl
(
std
::
false_type
,
key_type
const
&
key
,
F
&&
f
,
Args
&&
...
args
)
const
{
auto
it
=
cachedData_
.
find
(
key
);
if
(
it
!=
cachedData_
.
end
())
return
it
->
second
;
else
{
data_type
data
=
f
(
key
,
std
::
forward
<
Args
>
(
args
)...);
auto
it
=
cachedData_
.
emplace
(
key
,
std
::
move
(
data
));
return
it
.
first
->
second
;
}
}
mutable
container_type
cachedData_
;
};
// implementation of the ThreadLocal policy. Data is stored in thread_local variable.
template
<
class
Container
>
struct
ThreadLocalPolicy
{
...
...
@@ -113,7 +165,7 @@ namespace AMDiS
};
// implementation of the Shared policy
// implementation of the Shared policy
. Data is stored in static variable.
template
<
class
Container
>
struct
StaticLockedPolicy
{
...
...
@@ -151,7 +203,7 @@ namespace AMDiS
template
<
class
Key
,
class
Data
,
template
<
class
>
class
Policy
,
class
Container
>
class
ConcurrentCache
:
pr
ivate
Policy
<
Container
>
:
pr
otected
Policy
<
Container
>
{
using
key_type
=
Key
;
using
data_type
=
Data
;
...
...
@@ -167,7 +219,7 @@ namespace AMDiS
* \param args... Arguments passed additionally to the functor f
**/
template
<
class
F
,
class
...
Args
>
static
data_type
const
&
get
(
key_type
const
&
key
,
F
&&
f
,
Args
&&
...
args
)
data_type
const
&
get
(
key_type
const
&
key
,
F
&&
f
,
Args
&&
...
args
)
const
{
static_assert
(
Dune
::
Std
::
is_callable
<
F
(
key_type
,
Args
...),
data_type
>::
value
,
"Functor F must have the signature data_type(key_type, Args...)"
);
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment