Applying lazy evaluation to the BTI encoding of clustering keys was probably a bad default. The benefits are dubious (because it's quite likely that the laziness won't allow us to avoid that much work), but the overhead needed to implement the laziness is large and immediate. In this patch we get rid of the laziness. We rewrite lazy_comparable_bytes_from_clustering_position so that it performs the translation eagerly, all components to a single bytes_ostream. Note: the name *lazy*_comparable_bytes_from_clustering_position stays, because the interface is still lazy. perf_bti_key_translation: Before: test iterations median mad min max allocs tasks inst cycles lcb_mismatch_test.lcb_mismatch 9233 109.930us 0.000ns 109.930us 109.930us 4356.000 0.000 2615394.3 614709.6 After: test iterations median mad min max allocs tasks inst cycles lcb_mismatch_test.lcb_mismatch 50952 19.487us 0.000ns 19.487us 19.487us 198.000 0.000 603120.1 109042.9
69 lines
1.6 KiB
C++
69 lines
1.6 KiB
C++
/*
|
|
* Copyright (C) 2017-present ScyllaDB
|
|
*/
|
|
|
|
/*
|
|
* SPDX-License-Identifier: LicenseRef-ScyllaDB-Source-Available-1.0
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <string_view>
|
|
#include <seastar/core/sstring.hh>
|
|
|
|
#include "seastarx.hh"
|
|
|
|
template<typename CharT>
|
|
class basic_mutable_view {
|
|
CharT* _begin = nullptr;
|
|
CharT* _end = nullptr;
|
|
public:
|
|
using value_type = CharT;
|
|
using pointer = CharT*;
|
|
using iterator = CharT*;
|
|
using const_iterator = CharT*;
|
|
|
|
basic_mutable_view() = default;
|
|
|
|
template<typename U, U N>
|
|
basic_mutable_view(basic_sstring<CharT, U, N>& str)
|
|
: _begin(str.begin())
|
|
, _end(str.end())
|
|
{ }
|
|
|
|
basic_mutable_view(CharT* ptr, size_t length)
|
|
: _begin(ptr)
|
|
, _end(ptr + length)
|
|
{ }
|
|
|
|
operator std::basic_string_view<CharT>() const noexcept {
|
|
return std::basic_string_view<CharT>(begin(), size());
|
|
}
|
|
|
|
CharT& operator[](size_t idx) const { return _begin[idx]; }
|
|
|
|
iterator begin() const { return _begin; }
|
|
iterator end() const { return _end; }
|
|
|
|
CharT* data() const { return _begin; }
|
|
size_t size() const { return _end - _begin; }
|
|
bool empty() const { return _begin == _end; }
|
|
CharT& front() const { return *_begin; }
|
|
|
|
void remove_prefix(size_t n) {
|
|
_begin += n;
|
|
}
|
|
void remove_suffix(size_t n) {
|
|
_end -= n;
|
|
}
|
|
|
|
basic_mutable_view substr(size_t pos, size_t count) {
|
|
size_t n = std::min(count, (_end - _begin) - pos);
|
|
return basic_mutable_view{_begin + pos, n};
|
|
}
|
|
|
|
explicit operator std::span<CharT>() const noexcept {
|
|
return std::span<CharT>(_begin, _end);
|
|
}
|
|
};
|