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?
0diff --git a/src/dbwrapper.cpp b/src/dbwrapper.cpp
1index 1b2548f262..cb27b739fe 100644
2--- a/src/dbwrapper.cpp
3+++ b/src/dbwrapper.cpp
4@@ -335,11 +335,8 @@ std::vector<unsigned char> CDBWrapper::CreateObfuscateKey() const
5 return ret;
6 }
7
8-bool CDBWrapper::ReadImpl(std::function<void(DataStream&)> write_key_to_stream, std::function<void(CDataStream&)> read_value_from_stream) const
9+bool CDBWrapper::ReadImpl(const DataStream& ssKey, CDataStream& ssValue) const
10 {
11- DataStream ssKey{};
12- ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
13- write_key_to_stream(ssKey);
14 leveldb::Slice slKey(CharCast(ssKey.data()), ssKey.size());
15
16 std::string strValue;
17@@ -351,9 +348,8 @@ bool CDBWrapper::ReadImpl(std::function<void(DataStream&)> write_key_to_stream,
18 HandleError(status);
19 }
20 try {
21- CDataStream ssValue{MakeByteSpan(strValue), SER_DISK, CLIENT_VERSION};
22+ ssValue << MakeByteSpan(strValue);
23 ssValue.Xor(obfuscate_key);
24- read_value_from_stream(ssValue);
25 } catch (const std::exception&) {
26 return false;
27 }
28diff --git a/src/dbwrapper.h b/src/dbwrapper.h
29index e48d077a80..e9536b8e7a 100644
30--- a/src/dbwrapper.h
31+++ b/src/dbwrapper.h
32@@ -205,7 +205,7 @@ private:
33 //! whether or not the database resides in memory
34 bool m_is_memory;
35
36- bool ReadImpl(std::function<void(DataStream&)> write_key_to_stream, std::function<void(CDataStream&)> read_value_from_stream) const;
37+ bool ReadImpl(const DataStream& ssKey, CDataStream& ssValue) const;
38 bool ExistsImpl(const Span<const std::byte>& key) const;
39 size_t EstimateSizeImpl(const Span<const std::byte>& key1, const Span<const std::byte>& key2) const;
40 auto& DBContext() const { return *Assert(m_db_context); }
41@@ -220,9 +220,16 @@ public:
42 template <typename K, typename V>
43 bool Read(const K& key, V& value) const
44 {
45- auto write_key_to_stream{[&key](DataStream& ssKey) { ssKey << key; }};
46- auto read_value_from_stream{[&value](CDataStream& ssValue) { ssValue >> value; }};
47- return ReadImpl(write_key_to_stream, read_value_from_stream);
48+ DataStream ssKey{};
49+ ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
50+ ssKey << key;
51+
52+ CDataStream ssValue{SER_DISK, CLIENT_VERSION};
53+ if(ReadImpl(ssKey, ssValue)) {
54+ ssValue >> value;
55+ return true;
56+ }
57+ return false;
58 }
59
60 template <typename K, typename V>