The codebase evolved to have several different ways to hold a fragmented
buffer: fragmented_temporary_buffer (for data received from the network;
not relevant for this discussion); bytes_ostream (for fragmented data that
is built incrementally; also used for a serialized result_set), and
managed_bytes (used for lsa and serialized individual values in
expression evaluation).
One problem with this state of affairs is that using data in one
fragmented form with functions that accept another fragmented form
requires either a copy, or templating everything. The former is
unpalatable for fast-path code, and the latter is undesirable for
compile time and run-time code footprint. So we'd like to make
the various forms compatible.
In 53e0dc7530 ("bytes_ostream: base on managed_bytes") we changed
bytes_ostream to have the same underlying data structure as
managed_bytes, so all that remains is to add the right API. This
is somewhat difficult as the data is hidden in multiple layers:
ser::buffer_view<> is used to abstract a slice of bytes_ostream,
and this is further abstracted by using iterators into bytes_ostream
rather than directly using the internals. Likewise, it's impossible
to construct a managed_bytes_view from the internals.
Hack through all of these by adding extract_implementation() methods,
and a build_managed_bytes_view_from_internals() helper. These are all
used by new APIs buffer_view_to_managed_bytes_view() that extract
the internals and put them back together again.
Ideally we wouldn't need any of this, but unifying the type system
in this area is quite an undertaking, so we need some shortcuts.
39 lines
812 B
C++
39 lines
812 B
C++
/*
|
|
* Copyright (C) 2021-present ScyllaDB
|
|
*/
|
|
|
|
/*
|
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
|
*/
|
|
|
|
#include "serializer_impl.hh"
|
|
|
|
namespace ser {
|
|
|
|
logging::logger serlog("serializer");
|
|
|
|
} // namespace ser
|
|
|
|
namespace utils {
|
|
|
|
managed_bytes_view
|
|
buffer_view_to_managed_bytes_view(ser::buffer_view<bytes_ostream::fragment_iterator> bv) {
|
|
auto impl = bv.extract_implementation();
|
|
return build_managed_bytes_view_from_internals(
|
|
impl.current,
|
|
impl.next.extract_implementation().current_chunk,
|
|
impl.size
|
|
);
|
|
}
|
|
|
|
managed_bytes_view_opt
|
|
buffer_view_to_managed_bytes_view(std::optional<ser::buffer_view<bytes_ostream::fragment_iterator>> bvo) {
|
|
if (!bvo) {
|
|
return std::nullopt;
|
|
}
|
|
return buffer_view_to_managed_bytes_view(*bvo);
|
|
}
|
|
|
|
|
|
} // namespace utils
|