It's not immediately obvious to me why we can't stick to our usual pattern of using a const DataStream& ssKey, CDataStream& ssValue function signature, and instead resort to lambdas as is done here. I think the below code is much more straightforward, but perhaps I'm missing some nuance or drawbacks?
<details>
<summary>git diff on f26396732b940095380d76ed77685e0fb11294b8</summary>
diff --git a/src/dbwrapper.cpp b/src/dbwrapper.cpp
index 1b2548f262..cb27b739fe 100644
--- a/src/dbwrapper.cpp
+++ b/src/dbwrapper.cpp
@@ -335,11 +335,8 @@ std::vector<unsigned char> CDBWrapper::CreateObfuscateKey() const
return ret;
}
-bool CDBWrapper::ReadImpl(std::function<void(DataStream&)> write_key_to_stream, std::function<void(CDataStream&)> read_value_from_stream) const
+bool CDBWrapper::ReadImpl(const DataStream& ssKey, CDataStream& ssValue) const
{
- DataStream ssKey{};
- ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
- write_key_to_stream(ssKey);
leveldb::Slice slKey(CharCast(ssKey.data()), ssKey.size());
std::string strValue;
@@ -351,9 +348,8 @@ bool CDBWrapper::ReadImpl(std::function<void(DataStream&)> write_key_to_stream,
HandleError(status);
}
try {
- CDataStream ssValue{MakeByteSpan(strValue), SER_DISK, CLIENT_VERSION};
+ ssValue << MakeByteSpan(strValue);
ssValue.Xor(obfuscate_key);
- read_value_from_stream(ssValue);
} catch (const std::exception&) {
return false;
}
diff --git a/src/dbwrapper.h b/src/dbwrapper.h
index e48d077a80..e9536b8e7a 100644
--- a/src/dbwrapper.h
+++ b/src/dbwrapper.h
@@ -205,7 +205,7 @@ private:
//! whether or not the database resides in memory
bool m_is_memory;
- bool ReadImpl(std::function<void(DataStream&)> write_key_to_stream, std::function<void(CDataStream&)> read_value_from_stream) const;
+ bool ReadImpl(const DataStream& ssKey, CDataStream& ssValue) const;
bool ExistsImpl(const Span<const std::byte>& key) const;
size_t EstimateSizeImpl(const Span<const std::byte>& key1, const Span<const std::byte>& key2) const;
auto& DBContext() const { return *Assert(m_db_context); }
@@ -220,9 +220,16 @@ public:
template <typename K, typename V>
bool Read(const K& key, V& value) const
{
- auto write_key_to_stream{[&key](DataStream& ssKey) { ssKey << key; }};
- auto read_value_from_stream{[&value](CDataStream& ssValue) { ssValue >> value; }};
- return ReadImpl(write_key_to_stream, read_value_from_stream);
+ DataStream ssKey{};
+ ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
+ ssKey << key;
+
+ CDataStream ssValue{SER_DISK, CLIENT_VERSION};
+ if(ReadImpl(ssKey, ssValue)) {
+ ssValue >> value;
+ return true;
+ }
+ return false;
}
template <typename K, typename V>
</details>