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
007a64e7
Commit
007a64e7
authored
Jul 31, 2019
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implement an URI-based node ID
parent
52409b7e
Changes
8
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
258 additions
and
61 deletions
+258
-61
libcaf_core/CMakeLists.txt
libcaf_core/CMakeLists.txt
+1
-0
libcaf_core/caf/detail/fnv_hash.hpp
libcaf_core/caf/detail/fnv_hash.hpp
+71
-0
libcaf_core/caf/node_id.hpp
libcaf_core/caf/node_id.hpp
+46
-0
libcaf_core/caf/uri.hpp
libcaf_core/caf/uri.hpp
+14
-0
libcaf_core/src/fnv_hash.cpp
libcaf_core/src/fnv_hash.cpp
+62
-0
libcaf_core/src/node_id.cpp
libcaf_core/src/node_id.cpp
+47
-0
libcaf_core/src/uri.cpp
libcaf_core/src/uri.cpp
+5
-0
libcaf_io/src/ip_endpoint.cpp
libcaf_io/src/ip_endpoint.cpp
+12
-61
No files found.
libcaf_core/CMakeLists.txt
View file @
007a64e7
...
@@ -54,6 +54,7 @@ set(LIBCAF_CORE_SRCS
...
@@ -54,6 +54,7 @@ set(LIBCAF_CORE_SRCS
src/event_based_actor.cpp
src/event_based_actor.cpp
src/execution_unit.cpp
src/execution_unit.cpp
src/exit_reason.cpp
src/exit_reason.cpp
src/fnv_hash.cpp
src/forwarding_actor_proxy.cpp
src/forwarding_actor_proxy.cpp
src/get_mac_addresses.cpp
src/get_mac_addresses.cpp
src/get_process_id.cpp
src/get_process_id.cpp
...
...
libcaf_core/caf/detail/fnv_hash.hpp
0 → 100644
View file @
007a64e7
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright 2011-2019 Dominik Charousset *
* *
* Distributed under the terms and conditions of the BSD 3-Clause License or *
* (at your option) under the terms and conditions of the Boost Software *
* License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. *
* *
* If you did not receive a copy of the license files, see *
* http://opensource.org/licenses/BSD-3-Clause and *
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
#pragma once
#include <cstdint>
#include <type_traits>
#include "caf/detail/type_traits.hpp"
namespace
caf
{
namespace
detail
{
/// Non-cryptographic hash function named after Glenn Fowler, Landon Curt Noll,
/// and Kiem-Phong Vo.
///
/// See:
/// - https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function
/// - http://www.isthe.com/chongo/tech/comp/fnv/index.html
size_t
fnv_hash
(
const
unsigned
char
*
first
,
const
unsigned
char
*
last
);
size_t
fnv_hash_append
(
size_t
intermediate
,
const
unsigned
char
*
first
,
const
unsigned
char
*
last
);
template
<
class
T
>
enable_if_t
<
has_data_member
<
T
>::
value
,
size_t
>
fnv_hash
(
const
T
&
x
)
{
auto
ptr
=
x
.
data
();
auto
first
=
reinterpret_cast
<
const
uint8_t
*>
(
ptr
);
auto
last
=
first
+
(
sizeof
(
decay_t
<
decltype
(
*
ptr
)
>
)
*
x
.
size
());
return
fnv_hash
(
first
,
last
);
}
template
<
class
T
>
enable_if_t
<
has_data_member
<
T
>::
value
,
size_t
>
fnv_hash_append
(
size_t
intermediate
,
const
T
&
x
)
{
auto
ptr
=
x
.
data
();
auto
first
=
reinterpret_cast
<
const
uint8_t
*>
(
ptr
);
auto
last
=
first
+
(
sizeof
(
decay_t
<
decltype
(
*
ptr
)
>
)
*
x
.
size
());
return
fnv_hash_append
(
intermediate
,
first
,
last
);
}
template
<
class
T
>
enable_if_t
<
std
::
is_integral
<
T
>::
value
,
size_t
>
fnv_hash
(
const
T
&
x
)
{
auto
first
=
reinterpret_cast
<
const
uint8_t
*>
(
&
x
);
return
fnv_hash
(
first
,
first
+
sizeof
(
T
));
}
template
<
class
T
>
enable_if_t
<
std
::
is_integral
<
T
>::
value
,
size_t
>
fnv_hash_append
(
size_t
interim
,
const
T
&
x
)
{
auto
first
=
reinterpret_cast
<
const
uint8_t
*>
(
&
x
);
return
fnv_hash_append
(
interim
,
first
,
first
+
sizeof
(
T
));
}
}
// namespace detail
}
// namespace caf
libcaf_core/caf/node_id.hpp
View file @
007a64e7
...
@@ -29,6 +29,7 @@
...
@@ -29,6 +29,7 @@
#include "caf/intrusive_ptr.hpp"
#include "caf/intrusive_ptr.hpp"
#include "caf/none.hpp"
#include "caf/none.hpp"
#include "caf/ref_counted.hpp"
#include "caf/ref_counted.hpp"
#include "caf/uri.hpp"
namespace
caf
{
namespace
caf
{
...
@@ -125,6 +126,47 @@ public:
...
@@ -125,6 +126,47 @@ public:
host_id_type
host_
;
host_id_type
host_
;
};
};
// A technology-agnostic node identifier using an URI.
class
uri_data
final
:
public
data
{
public:
// -- constants ------------------------------------------------------------
/// Identifies this data implementation type.
static
constexpr
atom_value
class_id
=
atom
(
"uri"
);
// -- constructors, destructors, and assignment operators ------------------
explicit
uri_data
(
uri
value
);
// -- properties -----------------------------------------------------------
const
uri
&
value
()
const
noexcept
{
return
value_
;
}
// -- interface implementation ---------------------------------------------
bool
valid
()
const
noexcept
override
;
size_t
hash_code
()
const
noexcept
override
;
atom_value
implementation_id
()
const
noexcept
override
;
int
compare
(
const
data
&
other
)
const
noexcept
override
;
void
print
(
std
::
string
&
dst
)
const
override
;
error
serialize
(
serializer
&
sink
)
const
override
;
error
deserialize
(
deserializer
&
source
)
override
;
private:
// -- member variables -----------------------------------------------------
uri
value_
;
};
// -- constructors, destructors, and assignment operators --------------------
// -- constructors, destructors, and assignment operators --------------------
constexpr
node_id
()
noexcept
{
constexpr
node_id
()
noexcept
{
...
@@ -207,6 +249,10 @@ void append_to_string(std::string& str, const node_id& x);
...
@@ -207,6 +249,10 @@ void append_to_string(std::string& str, const node_id& x);
/// @relates node_id
/// @relates node_id
std
::
string
to_string
(
const
node_id
&
x
);
std
::
string
to_string
(
const
node_id
&
x
);
/// Creates a node ID from the URI `from`.
/// @relates node_id
node_id
make_node_id
(
uri
from
);
/// Creates a node ID from `process_id` and `host_id`.
/// Creates a node ID from `process_id` and `host_id`.
/// @param process_id System-wide unique process identifier.
/// @param process_id System-wide unique process identifier.
/// @param host_id Unique hash value representing a single CAF node.
/// @param host_id Unique hash value representing a single CAF node.
...
...
libcaf_core/caf/uri.hpp
View file @
007a64e7
...
@@ -105,6 +105,9 @@ public:
...
@@ -105,6 +105,9 @@ public:
/// Returns the fragment component.
/// Returns the fragment component.
string_view
fragment
()
const
noexcept
;
string_view
fragment
()
const
noexcept
;
/// Returns a hash code over all components.
size_t
hash_code
()
const
noexcept
;
// -- comparison -------------------------------------------------------------
// -- comparison -------------------------------------------------------------
int
compare
(
const
uri
&
other
)
const
noexcept
;
int
compare
(
const
uri
&
other
)
const
noexcept
;
...
@@ -135,3 +138,14 @@ std::string to_string(const uri& x);
...
@@ -135,3 +138,14 @@ std::string to_string(const uri& x);
error
parse
(
string_view
str
,
uri
&
dest
);
error
parse
(
string_view
str
,
uri
&
dest
);
}
// namespace caf
}
// namespace caf
namespace
std
{
template
<
>
struct
hash
<
caf
::
uri
>
{
size_t
operator
()(
const
caf
::
uri
&
x
)
const
noexcept
{
return
x
.
hash_code
();
}
};
}
// namespace std
libcaf_core/src/fnv_hash.cpp
0 → 100644
View file @
007a64e7
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright 2011-2019 Dominik Charousset *
* *
* Distributed under the terms and conditions of the BSD 3-Clause License or *
* (at your option) under the terms and conditions of the Boost Software *
* License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. *
* *
* If you did not receive a copy of the license files, see *
* http://opensource.org/licenses/BSD-3-Clause and *
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
#include "caf/detail/fnv_hash.hpp"
namespace
caf
{
namespace
detail
{
namespace
{
template
<
size_t
IntegerSize
>
struct
hash_conf_helper
;
template
<
>
struct
hash_conf_helper
<
4
>
{
static
constexpr
size_t
basis
=
2166136261u
;
static
constexpr
size_t
prime
=
16777619u
;
};
template
<
>
struct
hash_conf_helper
<
8
>
{
static
constexpr
size_t
basis
=
14695981039346656037u
;
static
constexpr
size_t
prime
=
1099511628211u
;
};
struct
hash_conf
:
hash_conf_helper
<
sizeof
(
size_t
)
>
{};
}
// namespace
size_t
fnv_hash
(
const
unsigned
char
*
first
,
const
unsigned
char
*
last
)
{
return
fnv_hash_append
(
hash_conf
::
basis
,
first
,
last
);
}
size_t
fnv_hash_append
(
size_t
intermediate
,
const
unsigned
char
*
first
,
const
unsigned
char
*
last
)
{
auto
result
=
intermediate
;
for
(;
first
!=
last
;
++
first
)
{
result
*=
hash_conf
::
prime
;
result
^=
*
first
;
}
return
result
;
}
}
// namespace detail
}
// namespace caf
libcaf_core/src/node_id.cpp
View file @
007a64e7
...
@@ -123,6 +123,48 @@ error node_id::default_data::deserialize(deserializer& source) {
...
@@ -123,6 +123,48 @@ error node_id::default_data::deserialize(deserializer& source) {
return
source
(
pid_
,
host_
);
return
source
(
pid_
,
host_
);
}
}
node_id
::
uri_data
::
uri_data
(
uri
value
)
:
value_
(
std
::
move
(
value
))
{
// nop
}
bool
node_id
::
uri_data
::
valid
()
const
noexcept
{
return
!
value_
.
empty
();
}
size_t
node_id
::
uri_data
::
hash_code
()
const
noexcept
{
std
::
hash
<
uri
>
f
;
return
f
(
value_
);
}
atom_value
node_id
::
uri_data
::
implementation_id
()
const
noexcept
{
return
class_id
;
}
int
node_id
::
uri_data
::
compare
(
const
data
&
other
)
const
noexcept
{
if
(
this
==
&
other
)
return
0
;
auto
other_id
=
other
.
implementation_id
();
if
(
class_id
!=
other_id
)
return
caf
::
compare
(
class_id
,
other_id
);
return
value_
.
compare
(
static_cast
<
const
uri_data
&>
(
other
).
value_
);
}
void
node_id
::
uri_data
::
print
(
std
::
string
&
dst
)
const
{
if
(
!
valid
())
{
dst
+=
"invalid-node"
;
return
;
}
dst
+=
to_string
(
value_
);
}
error
node_id
::
uri_data
::
serialize
(
serializer
&
sink
)
const
{
return
sink
(
value_
);
}
error
node_id
::
uri_data
::
deserialize
(
deserializer
&
source
)
{
return
source
(
value_
);
}
node_id
&
node_id
::
operator
=
(
const
none_t
&
)
{
node_id
&
node_id
::
operator
=
(
const
none_t
&
)
{
data_
.
reset
();
data_
.
reset
();
return
*
this
;
return
*
this
;
...
@@ -203,6 +245,11 @@ std::string to_string(const node_id& x) {
...
@@ -203,6 +245,11 @@ std::string to_string(const node_id& x) {
return
result
;
return
result
;
}
}
node_id
make_node_id
(
uri
from
)
{
auto
ptr
=
make_counted
<
node_id
::
uri_data
>
(
std
::
move
(
from
));
return
node_id
{
std
::
move
(
ptr
)};
}
node_id
make_node_id
(
uint32_t
process_id
,
node_id
make_node_id
(
uint32_t
process_id
,
const
node_id
::
default_data
::
host_id_type
&
host_id
)
{
const
node_id
::
default_data
::
host_id_type
&
host_id
)
{
auto
ptr
=
make_counted
<
node_id
::
default_data
>
(
process_id
,
host_id
);
auto
ptr
=
make_counted
<
node_id
::
default_data
>
(
process_id
,
host_id
);
...
...
libcaf_core/src/uri.cpp
View file @
007a64e7
...
@@ -19,6 +19,7 @@
...
@@ -19,6 +19,7 @@
#include "caf/uri.hpp"
#include "caf/uri.hpp"
#include "caf/deserializer.hpp"
#include "caf/deserializer.hpp"
#include "caf/detail/fnv_hash.hpp"
#include "caf/detail/parser/read_uri.hpp"
#include "caf/detail/parser/read_uri.hpp"
#include "caf/detail/uri_impl.hpp"
#include "caf/detail/uri_impl.hpp"
#include "caf/error.hpp"
#include "caf/error.hpp"
...
@@ -64,6 +65,10 @@ string_view uri::fragment() const noexcept {
...
@@ -64,6 +65,10 @@ string_view uri::fragment() const noexcept {
return
impl_
->
fragment
;
return
impl_
->
fragment
;
}
}
size_t
uri
::
hash_code
()
const
noexcept
{
return
detail
::
fnv_hash
(
str
());
}
// -- comparison ---------------------------------------------------------------
// -- comparison ---------------------------------------------------------------
int
uri
::
compare
(
const
uri
&
other
)
const
noexcept
{
int
uri
::
compare
(
const
uri
&
other
)
const
noexcept
{
...
...
libcaf_io/src/ip_endpoint.cpp
View file @
007a64e7
...
@@ -18,10 +18,10 @@
...
@@ -18,10 +18,10 @@
#include "caf/io/network/ip_endpoint.hpp"
#include "caf/io/network/ip_endpoint.hpp"
#include "caf/sec.hpp"
#include "caf/detail/fnv_hash.hpp"
#include "caf/logger.hpp"
#include "caf/io/network/native_socket.hpp"
#include "caf/io/network/native_socket.hpp"
#include "caf/logger.hpp"
#include "caf/sec.hpp"
#ifdef CAF_WINDOWS
#ifdef CAF_WINDOWS
# include <winsock2.h>
# include <winsock2.h>
...
@@ -41,41 +41,8 @@
...
@@ -41,41 +41,8 @@
using
sa_family_t
=
short
;
using
sa_family_t
=
short
;
#endif
#endif
namespace
{
using
caf
::
detail
::
fnv_hash
;
using
caf
::
detail
::
fnv_hash_append
;
template
<
class
SizeType
=
size_t
>
struct
hash_conf
{
template
<
class
T
=
SizeType
>
static
constexpr
caf
::
detail
::
enable_if_t
<
(
sizeof
(
T
)
==
4
),
size_t
>
basis
()
{
return
2166136261u
;
}
template
<
class
T
=
SizeType
>
static
constexpr
caf
::
detail
::
enable_if_t
<
(
sizeof
(
T
)
==
4
),
size_t
>
prime
()
{
return
16777619u
;
}
template
<
class
T
=
SizeType
>
static
constexpr
caf
::
detail
::
enable_if_t
<
(
sizeof
(
T
)
==
8
),
size_t
>
basis
()
{
return
14695981039346656037u
;
}
template
<
class
T
=
SizeType
>
static
constexpr
caf
::
detail
::
enable_if_t
<
(
sizeof
(
T
)
==
8
),
size_t
>
prime
()
{
return
1099511628211u
;
}
};
constexpr
uint8_t
static_bytes
[]
=
{
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0xFF
,
0xFF
};
constexpr
size_t
prehash
(
int
i
=
11
)
{
return
(
i
>
0
)
?
(
prehash
(
i
-
1
)
*
hash_conf
<>::
prime
())
^
static_bytes
[
i
]
:
(
hash_conf
<>::
basis
()
*
hash_conf
<>::
prime
())
^
static_bytes
[
i
];
}
}
// namespace <anonymous>
namespace
caf
{
namespace
caf
{
namespace
io
{
namespace
io
{
...
@@ -145,32 +112,16 @@ size_t ep_hash::operator()(const sockaddr& sa) const noexcept {
...
@@ -145,32 +112,16 @@ size_t ep_hash::operator()(const sockaddr& sa) const noexcept {
}
}
size_t
ep_hash
::
hash
(
const
sockaddr_in
*
sa
)
const
noexcept
{
size_t
ep_hash
::
hash
(
const
sockaddr_in
*
sa
)
const
noexcept
{
auto
&
addr
=
sa
->
sin_addr
;
auto
result
=
fnv_hash
(
sa
->
sin_addr
.
s_addr
);
size_t
res
=
prehash
();
result
=
fnv_hash_append
(
result
,
sa
->
sin_port
);
// the first loop was replaces with `constexpr size_t prehash()`
return
result
;
for
(
int
i
=
0
;
i
<
4
;
++
i
)
{
res
=
res
*
hash_conf
<>::
prime
();
res
=
res
^
((
addr
.
s_addr
>>
i
)
&
0xFF
);
}
res
=
res
*
hash_conf
<>::
prime
();
res
=
res
^
(
sa
->
sin_port
>>
1
);
res
=
res
*
hash_conf
<>::
prime
();
res
=
res
^
(
sa
->
sin_port
&
0xFF
);
return
res
;
}
}
size_t
ep_hash
::
hash
(
const
sockaddr_in6
*
sa
)
const
noexcept
{
size_t
ep_hash
::
hash
(
const
sockaddr_in6
*
sa
)
const
noexcept
{
auto
&
addr
=
sa
->
sin6_addr
;
auto
&
addr
=
sa
->
sin6_addr
.
s6_addr
;
size_t
res
=
hash_conf
<>::
basis
();
auto
result
=
fnv_hash
(
addr
,
addr
+
16
);
for
(
int
i
=
0
;
i
<
16
;
++
i
)
{
result
=
fnv_hash_append
(
result
,
sa
->
sin6_port
);
res
=
res
*
hash_conf
<>::
prime
();
return
result
;
res
=
res
^
addr
.
s6_addr
[
i
];
}
res
=
res
*
hash_conf
<>::
prime
();
res
=
res
^
(
sa
->
sin6_port
>>
1
);
res
=
res
*
hash_conf
<>::
prime
();
res
=
res
^
(
sa
->
sin6_port
&
0xFF
);
return
res
;
}
}
bool
operator
==
(
const
ip_endpoint
&
lhs
,
const
ip_endpoint
&
rhs
)
{
bool
operator
==
(
const
ip_endpoint
&
lhs
,
const
ip_endpoint
&
rhs
)
{
...
...
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