hashers: Mark hash updates noexcept

All those methods end up with library calls, whose code
is not marked noexcept, but is such according to code
itself or docs.

The primary goal is to make some repair partition_hasher
methods noexcept (next patch).

Signed-off-by: Pavel Emelyanov <xemul@scylladb.com>
This commit is contained in:
Pavel Emelyanov
2020-09-07 20:39:54 +03:00
parent f76c519c1f
commit 5adb8e555c
5 changed files with 30 additions and 22 deletions

View File

@@ -31,7 +31,7 @@
namespace query {
struct noop_hasher {
void update(const char* ptr, size_t length) { }
void update(const char* ptr, size_t length) noexcept { }
std::array<uint8_t, 16> finalize_array() { return std::array<uint8_t, 16>(); };
};
@@ -55,7 +55,7 @@ public:
template<typename T, typename... Args>
void feed_hash(const T& value, Args&&... args) {
std::visit([&] (auto& hasher) {
std::visit([&] (auto& hasher) noexcept -> void {
::feed_hash(hasher, value, std::forward<Args>(args)...);
}, _impl);
};
@@ -75,4 +75,4 @@ using using_hash_of_hash = std::negation<std::disjunction<std::is_same<Hasher, m
template<typename Hasher>
inline constexpr bool using_hash_of_hash_v = using_hash_of_hash<Hasher>::value;
}
}

View File

@@ -29,12 +29,20 @@ template <typename T> struct hasher_traits;
template <> struct hasher_traits<md5_hasher> { using impl_type = CryptoPP::Weak::MD5; };
template <> struct hasher_traits<sha256_hasher> { using impl_type = CryptoPP::SHA256; };
template <typename T, size_t size> struct cryptopp_hasher<T, size>::impl {
template<typename H>
concept HashUpdater =
requires(hasher_traits<H>::impl_type& h, const CryptoPP::byte* ptr, size_t size) {
{ h.Update(ptr, size) } noexcept -> std::same_as<void>;
};
template <typename T, size_t size>
requires HashUpdater<T>
struct cryptopp_hasher<T, size>::impl {
using impl_type = typename hasher_traits<T>::impl_type;
impl_type hash{};
void update(const char* ptr, size_t length) {
void update(const char* ptr, size_t length) noexcept {
using namespace CryptoPP;
static_assert(sizeof(char) == sizeof(byte), "Assuming lengths will be the same");
hash.Update(reinterpret_cast<const byte*>(ptr), length * sizeof(byte));
@@ -74,7 +82,7 @@ template <typename T, size_t size> std::array<uint8_t, size> cryptopp_hasher<T,
return _impl->finalize_array();
}
template <typename T, size_t size> void cryptopp_hasher<T, size>::update(const char* ptr, size_t length) { _impl->update(ptr, length); }
template <typename T, size_t size> void cryptopp_hasher<T, size>::update(const char* ptr, size_t length) noexcept { _impl->update(ptr, length); }
template <typename T, size_t size> bytes cryptopp_hasher<T, size>::calculate(const std::string_view& s) {
typename cryptopp_hasher<T, size>::impl::impl_type hash;

View File

@@ -40,7 +40,7 @@ public:
bytes finalize();
std::array<uint8_t, size> finalize_array();
void update(const char* ptr, size_t length) override;
void update(const char* ptr, size_t length) noexcept override;
// Use update and finalize to compute the hash over the full view.
static bytes calculate(const std::string_view& s);

View File

@@ -45,13 +45,13 @@
template<typename H>
concept Hasher =
requires(H& h, const char* ptr, size_t size) {
{ h.update(ptr, size) } -> std::same_as<void>;
{ h.update(ptr, size) } noexcept -> std::same_as<void>;
};
class hasher {
public:
virtual ~hasher() = default;
virtual void update(const char* ptr, size_t size) = 0;
virtual void update(const char* ptr, size_t size) noexcept = 0;
};
static_assert(Hasher<hasher>);
@@ -62,7 +62,7 @@ struct appending_hash;
template<typename H, typename T, typename... Args>
requires Hasher<H>
inline
void feed_hash(H& h, const T& value, Args&&... args) {
void feed_hash(H& h, const T& value, Args&&... args) noexcept {
appending_hash<T>()(h, value, std::forward<Args>(args)...);
};
@@ -70,7 +70,7 @@ template<typename T>
struct appending_hash<T, std::enable_if_t<std::is_arithmetic<T>::value>> {
template<typename H>
requires Hasher<H>
void operator()(H& h, T value) const {
void operator()(H& h, T value) const noexcept {
auto value_le = cpu_to_le(value);
h.update(reinterpret_cast<const char*>(&value_le), sizeof(T));
}
@@ -80,7 +80,7 @@ template<>
struct appending_hash<bool> {
template<typename H>
requires Hasher<H>
void operator()(H& h, bool value) const {
void operator()(H& h, bool value) const noexcept {
feed_hash(h, static_cast<uint8_t>(value));
}
};
@@ -89,7 +89,7 @@ template<typename T>
struct appending_hash<T, std::enable_if_t<std::is_enum<T>::value>> {
template<typename H>
requires Hasher<H>
void operator()(H& h, const T& value) const {
void operator()(H& h, const T& value) const noexcept {
feed_hash(h, static_cast<std::underlying_type_t<T>>(value));
}
};
@@ -98,7 +98,7 @@ template<typename T>
struct appending_hash<std::optional<T>> {
template<typename H>
requires Hasher<H>
void operator()(H& h, const std::optional<T>& value) const {
void operator()(H& h, const std::optional<T>& value) const noexcept {
if (value) {
feed_hash(h, true);
feed_hash(h, *value);
@@ -112,7 +112,7 @@ template<size_t N>
struct appending_hash<char[N]> {
template<typename H>
requires Hasher<H>
void operator()(H& h, const char (&value) [N]) const {
void operator()(H& h, const char (&value) [N]) const noexcept {
feed_hash(h, N);
h.update(value, N);
}
@@ -122,7 +122,7 @@ template<typename T>
struct appending_hash<std::vector<T>> {
template<typename H>
requires Hasher<H>
void operator()(H& h, const std::vector<T>& value) const {
void operator()(H& h, const std::vector<T>& value) const noexcept {
feed_hash(h, value.size());
for (auto&& v : value) {
appending_hash<T>()(h, v);
@@ -134,7 +134,7 @@ template<typename K, typename V>
struct appending_hash<std::map<K, V>> {
template<typename H>
requires Hasher<H>
void operator()(H& h, const std::map<K, V>& value) const {
void operator()(H& h, const std::map<K, V>& value) const noexcept {
feed_hash(h, value.size());
for (auto&& e : value) {
appending_hash<K>()(h, e.first);
@@ -147,7 +147,7 @@ template<>
struct appending_hash<sstring> {
template<typename H>
requires Hasher<H>
void operator()(H& h, const sstring& v) const {
void operator()(H& h, const sstring& v) const noexcept {
feed_hash(h, v.size());
h.update(reinterpret_cast<const char*>(v.cbegin()), v.size() * sizeof(sstring::value_type));
}
@@ -157,7 +157,7 @@ template<>
struct appending_hash<std::string> {
template<typename H>
requires Hasher<H>
void operator()(H& h, const std::string& v) const {
void operator()(H& h, const std::string& v) const noexcept {
feed_hash(h, v.size());
h.update(reinterpret_cast<const char*>(v.data()), v.size() * sizeof(std::string::value_type));
}
@@ -167,7 +167,7 @@ template<typename T, typename R>
struct appending_hash<std::chrono::duration<T, R>> {
template<typename H>
requires Hasher<H>
void operator()(H& h, std::chrono::duration<T, R> v) const {
void operator()(H& h, std::chrono::duration<T, R> v) const noexcept {
feed_hash(h, v.count());
}
};
@@ -176,7 +176,7 @@ template<typename Clock, typename Duration>
struct appending_hash<std::chrono::time_point<Clock, Duration>> {
template<typename H>
requires Hasher<H>
void operator()(H& h, std::chrono::time_point<Clock, Duration> v) const {
void operator()(H& h, std::chrono::time_point<Clock, Duration> v) const noexcept {
feed_hash(h, v.time_since_epoch().count());
}
};

View File

@@ -40,7 +40,7 @@ public:
XXH64_reset(&_state, seed);
}
void update(const char* ptr, size_t length) {
void update(const char* ptr, size_t length) noexcept {
XXH64_update(&_state, ptr, length);
}