Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
A
Actor Framework
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
cpp-libs
Actor Framework
Commits
016b497a
Commit
016b497a
authored
Mar 30, 2021
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Accelerate deserialization of hash-based node IDs
parent
b34f70a1
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
69 additions
and
1 deletion
+69
-1
libcaf_core/caf/node_id.hpp
libcaf_core/caf/node_id.hpp
+9
-1
libcaf_core/src/node_id.cpp
libcaf_core/src/node_id.cpp
+60
-0
No files found.
libcaf_core/caf/node_id.hpp
View file @
016b497a
...
@@ -158,7 +158,7 @@ public:
...
@@ -158,7 +158,7 @@ public:
// -- friend functions -------------------------------------------------------
// -- friend functions -------------------------------------------------------
template
<
class
Inspector
>
template
<
class
Inspector
>
friend
bool
inspect
(
Inspector
&
f
,
node_id
&
x
)
{
friend
bool
default_
inspect
(
Inspector
&
f
,
node_id
&
x
)
{
auto
is_present
=
[
&
x
]
{
return
x
.
data_
!=
nullptr
;
};
auto
is_present
=
[
&
x
]
{
return
x
.
data_
!=
nullptr
;
};
auto
get
=
[
&
]()
->
const
auto
&
{
auto
get
=
[
&
]()
->
const
auto
&
{
return
x
.
data_
->
content
;
return
x
.
data_
->
content
;
...
@@ -174,6 +174,11 @@ public:
...
@@ -174,6 +174,11 @@ public:
return
f
.
object
(
x
).
fields
(
f
.
field
(
"data"
,
is_present
,
get
,
reset
,
set
));
return
f
.
object
(
x
).
fields
(
f
.
field
(
"data"
,
is_present
,
get
,
reset
,
set
));
}
}
template
<
class
Inspector
>
friend
bool
inspect
(
Inspector
&
f
,
node_id
&
x
)
{
return
default_inspect
(
f
,
x
);
}
// -- private API ------------------------------------------------------------
// -- private API ------------------------------------------------------------
/// @cond PRIVATE
/// @cond PRIVATE
...
@@ -200,6 +205,9 @@ private:
...
@@ -200,6 +205,9 @@ private:
intrusive_ptr
<
node_id_data
>
data_
;
intrusive_ptr
<
node_id_data
>
data_
;
};
};
/// @relates node_id
CAF_CORE_EXPORT
bool
inspect
(
binary_deserializer
&
f
,
node_id
&
x
);
/// Returns whether `x` contains an URI.
/// Returns whether `x` contains an URI.
/// @relates node_id
/// @relates node_id
inline
bool
wraps_uri
(
const
node_id
&
x
)
noexcept
{
inline
bool
wraps_uri
(
const
node_id
&
x
)
noexcept
{
...
...
libcaf_core/src/node_id.cpp
View file @
016b497a
...
@@ -19,6 +19,7 @@
...
@@ -19,6 +19,7 @@
#include "caf/detail/get_mac_addresses.hpp"
#include "caf/detail/get_mac_addresses.hpp"
#include "caf/detail/get_process_id.hpp"
#include "caf/detail/get_process_id.hpp"
#include "caf/detail/get_root_uuid.hpp"
#include "caf/detail/get_root_uuid.hpp"
#include "caf/detail/network_order.hpp"
#include "caf/detail/parse.hpp"
#include "caf/detail/parse.hpp"
#include "caf/detail/parser/ascii_to_int.hpp"
#include "caf/detail/parser/ascii_to_int.hpp"
#include "caf/detail/ripemd_160.hpp"
#include "caf/detail/ripemd_160.hpp"
...
@@ -162,6 +163,65 @@ bool node_id::can_parse(string_view str) noexcept {
...
@@ -162,6 +163,65 @@ bool node_id::can_parse(string_view str) noexcept {
return
default_data
::
can_parse
(
str
)
||
uri
::
can_parse
(
str
);
return
default_data
::
can_parse
(
str
)
||
uri
::
can_parse
(
str
);
}
}
namespace
{
constexpr
size_t
packed_size
=
24
;
// 20 bytes host ID + 4 bytes process ID
using
packed_hashed_node_id
=
std
::
array
<
uint8_t
,
packed_size
>
;
struct
fnv_hasher
{
size_t
operator
()(
const
packed_hashed_node_id
&
x
)
const
noexcept
{
return
hash
::
fnv
<
size_t
>::
compute
(
x
);
}
};
constexpr
size_t
max_node_id_cache_size
=
500
;
thread_local
std
::
unordered_map
<
packed_hashed_node_id
,
node_id
,
fnv_hasher
>
node_id_cache
;
}
// namespace
bool
inspect
(
binary_deserializer
&
f
,
node_id
&
x
)
{
auto
pos
=
f
.
current
();
auto
eos
=
f
.
end
();
if
(
pos
==
eos
)
{
f
.
emplace_error
(
sec
::
end_of_stream
);
return
false
;
}
// The first byte is the index for the variant:
// * -1 means invalid ID (is_present in default_inspect would return false)
// * 0 means URI-based ID
// * 1 means hash-based ID
if
(
static_cast
<
int8_t
>
(
*
pos
)
==
1
)
{
++
pos
;
if
(
eos
-
pos
<
static_cast
<
ptrdiff_t
>
(
packed_size
))
{
f
.
emplace_error
(
sec
::
end_of_stream
);
return
false
;
}
packed_hashed_node_id
packed
;
for
(
size_t
index
=
0
;
index
<
packed_size
;
++
index
)
packed
[
index
]
=
static_cast
<
uint8_t
>
(
*
pos
++
);
if
(
auto
i
=
node_id_cache
.
find
(
packed
);
i
!=
node_id_cache
.
end
())
{
x
=
i
->
second
;
}
else
{
uint32_t
proc_id
;
memcpy
(
&
proc_id
,
packed
.
data
(),
sizeof
(
uint32_t
));
proc_id
=
detail
::
from_network_order
(
proc_id
);
hashed_node_id
::
host_id_type
host_id
;
memcpy
(
host_id
.
data
(),
packed
.
data
()
+
sizeof
(
uint32_t
),
host_id
.
size
());
x
=
make_node_id
(
proc_id
,
host_id
);
if
(
node_id_cache
.
size
()
==
max_node_id_cache_size
)
node_id_cache
.
clear
();
node_id_cache
.
emplace
(
packed
,
x
);
}
f
.
skip
(
packed_size
+
1
);
return
true
;
}
else
{
return
default_inspect
(
f
,
x
);
}
}
void
append_to_string
(
std
::
string
&
str
,
const
node_id
&
x
)
{
void
append_to_string
(
std
::
string
&
str
,
const
node_id
&
x
)
{
auto
f
=
[
&
str
](
auto
&
x
)
{
auto
f
=
[
&
str
](
auto
&
x
)
{
if
constexpr
(
std
::
is_same
<
std
::
decay_t
<
decltype
(
x
)
>
,
uri
>::
value
)
if
constexpr
(
std
::
is_same
<
std
::
decay_t
<
decltype
(
x
)
>
,
uri
>::
value
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a 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