mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-06-01 00:34:01 +02:00
dbwrapper: reuse iterator scratch stream
`CDBIterator::Seek()` and `CDBIterator::GetValue()` only need a temporary owning buffer for immediate use. Keep one preallocated `DataStream` scratch member on the non-copyable iterator and guard each use with `ScopedDataStreamUsage`. `SeekImpl()` consumes the serialized key during the immediate LevelDB seek, and `GetValue()` still copies LevelDB value bytes into the owning scratch stream before in-place deobfuscation. A single stream is enough because these methods cannot overlap on the same iterator without re-entering or concurrently using it, which the guard asserts against. The preceding test covers repeated seeks and failed value deserialization followed by a successful read from the same entry. Co-authored-by: Andrew Toth <andrewstoth@gmail.com>
This commit is contained in:
@@ -360,7 +360,10 @@ struct CDBIterator::IteratorImpl {
|
||||
};
|
||||
|
||||
CDBIterator::CDBIterator(const CDBWrapper& _parent, std::unique_ptr<IteratorImpl> _piter) : parent(_parent),
|
||||
m_impl_iter(std::move(_piter)) {}
|
||||
m_impl_iter(std::move(_piter))
|
||||
{
|
||||
m_scratch.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
|
||||
}
|
||||
|
||||
CDBIterator* CDBWrapper::NewIterator()
|
||||
{
|
||||
|
||||
@@ -121,6 +121,7 @@ public:
|
||||
private:
|
||||
const CDBWrapper &parent;
|
||||
const std::unique_ptr<IteratorImpl> m_impl_iter;
|
||||
DataStream m_scratch{};
|
||||
|
||||
void SeekImpl(std::span<const std::byte> key);
|
||||
std::span<const std::byte> GetKeyImpl() const;
|
||||
@@ -140,10 +141,9 @@ public:
|
||||
void SeekToFirst();
|
||||
|
||||
template<typename K> void Seek(const K& key) {
|
||||
DataStream ssKey{};
|
||||
ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
|
||||
ssKey << key;
|
||||
SeekImpl(ssKey);
|
||||
ScopedDataStreamUsage scoped_scratch{m_scratch};
|
||||
m_scratch << key;
|
||||
SeekImpl(m_scratch);
|
||||
}
|
||||
|
||||
void Next();
|
||||
@@ -160,9 +160,10 @@ public:
|
||||
|
||||
template<typename V> bool GetValue(V& value) {
|
||||
try {
|
||||
DataStream ssValue{GetValueImpl()};
|
||||
dbwrapper_private::GetObfuscation(parent)(ssValue);
|
||||
ssValue >> value;
|
||||
ScopedDataStreamUsage scoped_scratch{m_scratch};
|
||||
m_scratch.write(GetValueImpl());
|
||||
dbwrapper_private::GetObfuscation(parent)(m_scratch);
|
||||
m_scratch >> value;
|
||||
} catch (const std::exception&) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user