Skip to content

Commit 23259bd

Browse files
authored
Merge pull request #12255 from NaN-git/fix-7359
SinkToSource: avoid heap allocation
2 parents c000c16 + 4f8f12f commit 23259bd

File tree

1 file changed

+19
-16
lines changed

1 file changed

+19
-16
lines changed

src/libutil/serialise.cc

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -227,8 +227,7 @@ std::unique_ptr<FinishSink> sourceToSink(std::function<void(Source &)> fun)
227227
throw EndOfFile("coroutine has finished");
228228
}
229229

230-
size_t n = std::min(cur.size(), out_len);
231-
memcpy(out, cur.data(), n);
230+
size_t n = cur.copy(out, out_len);
232231
cur.remove_prefix(n);
233232
return n;
234233
});
@@ -260,7 +259,7 @@ std::unique_ptr<Source> sinkToSource(
260259
{
261260
struct SinkToSource : Source
262261
{
263-
typedef boost::coroutines2::coroutine<std::string> coro_t;
262+
typedef boost::coroutines2::coroutine<std::string_view> coro_t;
264263

265264
std::function<void(Sink &)> fun;
266265
std::function<void()> eof;
@@ -271,33 +270,37 @@ std::unique_ptr<Source> sinkToSource(
271270
{
272271
}
273272

274-
std::string cur;
275-
size_t pos = 0;
273+
std::string_view cur;
276274

277275
size_t read(char * data, size_t len) override
278276
{
279-
if (!coro) {
277+
bool hasCoro = coro.has_value();
278+
if (!hasCoro) {
280279
coro = coro_t::pull_type([&](coro_t::push_type & yield) {
281280
LambdaSink sink([&](std::string_view data) {
282-
if (!data.empty()) yield(std::string(data));
281+
if (!data.empty()) {
282+
yield(data);
283+
}
283284
});
284285
fun(sink);
285286
});
286287
}
287288

288-
if (!*coro) { eof(); unreachable(); }
289-
290-
if (pos == cur.size()) {
291-
if (!cur.empty()) {
289+
if (cur.empty()) {
290+
if (hasCoro) {
292291
(*coro)();
293292
}
294-
cur = coro->get();
295-
pos = 0;
293+
if (*coro) {
294+
cur = coro->get();
295+
} else {
296+
coro.reset();
297+
eof();
298+
unreachable();
299+
}
296300
}
297301

298-
auto n = std::min(cur.size() - pos, len);
299-
memcpy(data, cur.data() + pos, n);
300-
pos += n;
302+
size_t n = cur.copy(data, len);
303+
cur.remove_prefix(n);
301304

302305
return n;
303306
}

0 commit comments

Comments
 (0)