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
384c78a6
Commit
384c78a6
authored
Apr 26, 2017
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Allow subtypes of `downstream<T>`
parent
f22bf810
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
112 additions
and
79 deletions
+112
-79
libcaf_core/caf/abstract_downstream.hpp
libcaf_core/caf/abstract_downstream.hpp
+59
-10
libcaf_core/caf/downstream.hpp
libcaf_core/caf/downstream.hpp
+23
-44
libcaf_core/caf/stream_stage_impl.hpp
libcaf_core/caf/stream_stage_impl.hpp
+23
-3
libcaf_core/src/abstract_downstream.cpp
libcaf_core/src/abstract_downstream.cpp
+7
-22
No files found.
libcaf_core/caf/abstract_downstream.hpp
View file @
384c78a6
...
...
@@ -63,13 +63,40 @@ public:
virtual
~
abstract_downstream
();
/// Returns the total available credit for all sinks in O(n).
/// Returns the total available credit for all sinks in `xs` in O(n).
template
<
class
PathContainer
>
static
size_t
total_credit
(
const
PathContainer
&
xs
)
{
return
fold
(
xs
,
0u
,
[](
size_t
x
,
const
typename
PathContainer
::
value_type
&
y
)
{
return
x
+
y
->
open_credit
;
});
}
/// Returns the total available credit for all sinks in `paths_` in O(n).
size_t
total_credit
()
const
;
/// Returns the maximum credit of all sinks in O(n).
/// Returns the maximum credit of all sinks in `paths_` in O(n).
template
<
class
PathContainer
>
static
size_t
max_credit
(
const
PathContainer
&
xs
)
{
return
fold
(
xs
,
0
,
[](
size_t
x
,
const
typename
PathContainer
::
value_type
&
y
)
{
return
std
::
max
(
x
,
y
->
open_credit
);
});
}
/// Returns the maximum credit of all sinks in `paths_` in O(n).
size_t
max_credit
()
const
;
/// Returns the minimal credit of all sinks in O(n).
/// Returns the minimal credit of all sinks in `xs` in O(n).
template
<
class
PathContainer
>
static
size_t
min_credit
(
const
PathContainer
&
xs
)
{
return
fold
(
xs
,
std
::
numeric_limits
<
size_t
>::
max
(),
[](
size_t
x
,
const
typename
PathContainer
::
value_type
&
y
)
{
return
std
::
min
(
x
,
y
->
open_credit
);
});
}
/// Returns the minimal credit of all sinks in `paths_` in O(n).
size_t
min_credit
()
const
;
/// Broadcasts the first `*hint` elements of the buffer on all paths. If
...
...
@@ -99,7 +126,19 @@ public:
/// Sends an abort message to all paths and closes the stream.
void
abort
(
strong_actor_ptr
&
cause
,
const
error
&
reason
);
optional
<
path
&>
find
(
const
strong_actor_ptr
&
ptr
)
const
;
template
<
class
PathContainer
>
static
path
*
find
(
PathContainer
&
xs
,
const
strong_actor_ptr
&
ptr
)
{
auto
predicate
=
[
&
](
const
typename
PathContainer
::
value_type
&
y
)
{
return
y
->
hdl
==
ptr
;
};
auto
e
=
xs
.
end
();
auto
i
=
std
::
find_if
(
xs
.
begin
(),
e
,
predicate
);
if
(
i
!=
e
)
return
&
(
*
(
*
i
));
// Ugly, but works for both raw and smart pointers.
return
nullptr
;
}
path
*
find
(
const
strong_actor_ptr
&
ptr
)
const
;
size_t
available_credit
()
const
;
...
...
@@ -122,15 +161,25 @@ public:
protected:
void
send_batch
(
downstream_path
&
dest
,
size_t
chunk_size
,
message
chunk
);
/// Sorts `xs` in descending order by available credit.
template
<
class
PathContainer
>
static
void
sort_by_credit
(
PathContainer
&
xs
)
{
using
value_type
=
typename
PathContainer
::
value_type
;
auto
cmp
=
[](
const
value_type
&
x
,
const
value_type
&
y
)
{
return
x
->
open_credit
>
y
->
open_credit
;
};
std
::
sort
(
xs
.
begin
(),
xs
.
end
(),
cmp
);
}
/// Sorts `paths_` in descending order by available credit.
void
sort_by_credit
();
template
<
class
F
>
s
ize_t
fold_paths
(
size_t
init
,
F
f
)
const
{
auto
b
=
paths_
.
begin
();
auto
e
=
paths_
.
end
();
auto
g
=
[
&
](
size_t
x
,
const
path_uptr
&
y
)
{
return
f
(
x
,
*
y
);
template
<
class
PathContainer
,
class
F
>
s
tatic
size_t
fold
(
PathContainer
&
xs
,
size_t
init
,
F
f
)
{
auto
b
=
xs
.
begin
();
auto
e
=
xs
.
end
();
auto
g
=
[
&
](
size_t
x
,
const
typename
PathContainer
::
value_type
&
y
)
{
return
f
(
x
,
y
);
};
return
b
!=
e
?
std
::
accumulate
(
b
,
e
,
init
,
g
)
:
0
;
}
...
...
libcaf_core/caf/downstream.hpp
View file @
384c78a6
...
...
@@ -30,10 +30,13 @@
namespace
caf
{
template
<
class
T
>
class
downstream
final
:
public
abstract_downstream
{
class
downstream
:
public
abstract_downstream
{
public:
/// A chunk of data for sending batches downstream.
using
chunk
=
std
::
vector
<
T
>
;
using
chunk_type
=
std
::
vector
<
T
>
;
/// A queue of items for temporary storage before moving them into chunks.
using
queue_type
=
std
::
deque
<
T
>
;
downstream
(
local_actor
*
ptr
,
const
stream_id
&
sid
,
typename
abstract_downstream
::
policy_ptr
pptr
)
...
...
@@ -46,11 +49,11 @@ public:
buf_
.
emplace_back
(
std
::
forward
<
Ts
>
(
xs
)...);
}
std
::
deque
<
T
>
&
buf
()
{
queue_type
&
buf
()
{
return
buf_
;
}
const
std
::
deque
<
T
>
&
buf
()
const
{
const
queue_type
&
buf
()
const
{
return
buf_
;
}
...
...
@@ -67,15 +70,14 @@ public:
}
void
anycast
(
size_t
*
)
override
{
sort_by_credit
();
this
->
sort_by_credit
();
for
(
auto
&
x
:
paths_
)
{
auto
chunk
=
get_chunk
(
x
->
open_credit
);
auto
csize
=
chunk
.
size
();
if
(
csize
==
0
)
return
;
x
->
open_credit
-=
csize
;
auto
wrapped_chunk
=
make_message
(
std
::
move
(
chunk
));
send_batch
(
*
x
,
csize
,
std
::
move
(
wrapped_chunk
));
send_batch
(
*
x
,
csize
,
std
::
move
(
make_message
(
std
::
move
(
chunk
))));
}
}
...
...
@@ -83,54 +85,31 @@ public:
return
buf_
.
size
();
}
private:
/// Returns the minimum of `desired` and `buf_.size()`.
size_t
clamp_chunk_size
(
size_t
desired
)
const
{
return
std
::
min
(
desired
,
buf_
.
size
());
}
using
scratch_space_value
=
std
::
tuple
<
T
,
bool
,
atom_value
>
;
using
scratch_space
=
std
::
vector
<
scratch_space_value
>
;
/// Iterator over a `scratch_space` that behaves like a move
/// iterator over `vector<T>`.
struct
scratch_space_move_iter
{
typename
scratch_space
::
iterator
i
;
scratch_space_move_iter
&
operator
++
()
{
++
i
;
return
*
this
;
}
T
&&
operator
*
()
{
return
std
::
move
(
std
::
get
<
0
>
(
*
i
));
}
bool
operator
!=
(
const
scratch_space_move_iter
&
x
)
{
return
i
!=
x
.
i
;
}
};
protected:
/// @pre `n <= buf_.size()`
chunk
get_chunk
(
size_t
n
)
{
chunk
xs
;
static
chunk_type
get_chunk
(
queue_type
&
buf
,
size_t
n
)
{
chunk
_type
xs
;
if
(
n
>
0
)
{
xs
.
reserve
(
n
);
if
(
n
<
buf
_
.
size
())
{
auto
first
=
buf
_
.
begin
();
if
(
n
<
buf
.
size
())
{
auto
first
=
buf
.
begin
();
auto
last
=
first
+
static_cast
<
ptrdiff_t
>
(
n
);
std
::
move
(
first
,
last
,
std
::
back_inserter
(
xs
));
buf
_
.
erase
(
first
,
last
);
buf
.
erase
(
first
,
last
);
}
else
{
std
::
move
(
buf
_
.
begin
(),
buf_
.
end
(),
std
::
back_inserter
(
xs
));
buf
_
.
clear
();
std
::
move
(
buf
.
begin
(),
buf
.
end
(),
std
::
back_inserter
(
xs
));
buf
.
clear
();
}
}
return
xs
;
}
std
::
deque
<
T
>
buf_
;
/// @pre `n <= buf_.size()`
chunk_type
get_chunk
(
size_t
n
)
{
return
get_chunk
(
buf_
,
n
);
}
queue_type
buf_
;
};
}
// namespace caf
...
...
libcaf_core/caf/stream_stage_impl.hpp
View file @
384c78a6
...
...
@@ -27,7 +27,15 @@
namespace
caf
{
template
<
class
Fun
,
class
Cleanup
>
struct
default_stream_stage_policy
{
template
<
class
InputType
>
using
upstream_type
=
upstream
<
InputType
>
;
template
<
class
OutputType
>
using
downstream_type
=
downstream
<
OutputType
>
;
};
template
<
class
Fun
,
class
Cleanup
,
class
Policy
=
default_stream_stage_policy
>
class
stream_stage_impl
:
public
stream_stage
{
public:
using
trait
=
stream_stage_trait_t
<
Fun
>
;
...
...
@@ -38,6 +46,10 @@ public:
using
output_type
=
typename
trait
::
output
;
using
upstream_type
=
typename
Policy
::
template
upstream_type
<
output_type
>;
using
downstream_type
=
typename
Policy
::
template
downstream_type
<
output_type
>;
stream_stage_impl
(
local_actor
*
self
,
const
stream_id
&
sid
,
typename
abstract_upstream
::
policy_ptr
in_policy
,
...
...
@@ -86,12 +98,20 @@ public:
return
state_
;
}
upstream_type
&
in
()
{
return
in_
;
}
downstream_type
&
out
()
{
return
out_
;
}
private:
state_type
state_
;
Fun
fun_
;
Cleanup
cleanup_
;
upstream
<
output_type
>
in_
;
downstream
<
input_type
>
out_
;
upstream
_type
in_
;
downstream
_type
out_
;
};
}
// namespace caf
...
...
libcaf_core/src/abstract_downstream.cpp
View file @
384c78a6
...
...
@@ -41,20 +41,15 @@ abstract_downstream::~abstract_downstream() {
}
size_t
abstract_downstream
::
total_credit
()
const
{
auto
f
=
[](
size_t
x
,
path_cref
y
)
{
return
x
+
y
.
open_credit
;
};
return
fold_paths
(
0
,
f
);
return
total_credit
(
paths_
);
}
size_t
abstract_downstream
::
max_credit
()
const
{
auto
f
=
[](
size_t
x
,
path_cref
y
)
{
return
std
::
max
(
x
,
y
.
open_credit
);
};
return
fold_paths
(
0
,
f
);
return
max_credit
(
paths_
);
}
size_t
abstract_downstream
::
min_credit
()
const
{
auto
f
=
[](
size_t
x
,
path_cref
y
)
{
return
std
::
min
(
x
,
y
.
open_credit
);
};
return
fold_paths
(
std
::
numeric_limits
<
size_t
>::
max
(),
f
);
return
min_credit
(
paths_
);
}
bool
abstract_downstream
::
add_path
(
strong_actor_ptr
ptr
)
{
...
...
@@ -116,16 +111,9 @@ void abstract_downstream::abort(strong_actor_ptr& cause, const error& reason) {
make
<
stream_msg
::
abort
>
(
this
->
sid_
,
reason
));
}
auto
abstract_downstream
::
find
(
const
strong_actor_ptr
&
ptr
)
const
->
optional
<
path
&>
{
auto
predicate
=
[
&
](
const
path_uptr
&
y
)
{
return
y
->
hdl
==
ptr
;
};
auto
e
=
paths_
.
end
();
auto
i
=
std
::
find_if
(
paths_
.
begin
(),
e
,
predicate
);
if
(
i
!=
e
)
return
*
(
*
i
);
return
none
;
abstract_downstream
::
path
*
abstract_downstream
::
find
(
const
strong_actor_ptr
&
ptr
)
const
{
return
find
(
paths_
,
ptr
);
}
size_t
abstract_downstream
::
available_credit
()
const
{
...
...
@@ -143,10 +131,7 @@ void abstract_downstream::send_batch(downstream_path& dest, size_t chunk_size,
}
void
abstract_downstream
::
sort_by_credit
()
{
auto
cmp
=
[](
const
path_uptr
&
x
,
const
path_uptr
&
y
)
{
return
x
->
open_credit
>
y
->
open_credit
;
};
std
::
sort
(
paths_
.
begin
(),
paths_
.
end
(),
cmp
);
sort_by_credit
(
paths_
);
}
}
// namespace caf
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