dbwrapper: guard CDBBatch scratch streams

`CDBBatch` already owns key and value serialization buffers, but manually reserved and cleared them on each call.

Reserve those scratch buffers once in the constructor, then guard `Write()` and `Erase()` use with `ScopedDataStreamUsage`, requiring empty streams on entry and clearing them on every exit path.
`WriteImpl()` and `EraseImpl()` pass the bytes immediately to LevelDB's write batch, which copies them and does not retain pointers.

`Clear()` now asserts the guards left both scratch streams clean.

Co-authored-by: Andrew Toth <andrewstoth@gmail.com>
This commit is contained in:
Lőrinc
2026-04-24 22:14:17 +02:00
parent cb1ab0a716
commit 7403c0f907
2 changed files with 17 additions and 17 deletions

View File

@@ -163,6 +163,8 @@ CDBBatch::CDBBatch(const CDBWrapper& _parent)
: parent{_parent},
m_impl_batch{std::make_unique<CDBBatch::WriteBatchImpl>()}
{
m_key_scratch.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
m_value_scratch.reserve(DBWRAPPER_PREALLOC_VALUE_SIZE);
Clear();
};
@@ -171,13 +173,15 @@ CDBBatch::~CDBBatch() = default;
void CDBBatch::Clear()
{
m_impl_batch->batch.Clear();
assert(m_key_scratch.empty());
assert(m_value_scratch.empty());
}
void CDBBatch::WriteImpl(std::span<const std::byte> key, DataStream& ssValue)
void CDBBatch::WriteImpl(std::span<const std::byte> key, DataStream& value)
{
leveldb::Slice slKey(CharCast(key.data()), key.size());
dbwrapper_private::GetObfuscation(parent)(ssValue);
leveldb::Slice slValue(CharCast(ssValue.data()), ssValue.size());
dbwrapper_private::GetObfuscation(parent)(value);
leveldb::Slice slValue(CharCast(value.data()), value.size());
m_impl_batch->batch.Put(slKey, slValue);
}