Skip to content

Commit

Permalink
Remove usage of reduce in maxReadQuotaForKey, simplify accounting dat…
Browse files Browse the repository at this point in the history
…a structure (#4419)

# Description

Remove usage of `std::reduce` from `LedgerKeyMeter::maxReadQuotaForKey`

# Checklist
- [ ] Reviewed the
[contributing](https://github.com/stellar/stellar-core/blob/master/CONTRIBUTING.md#submitting-changes)
document
- [ ] Rebased on top of master (no merge commits)
- [ ] Ran `clang-format` v8.0.0 (via `make format` or the Visual Studio
extension)
- [ ] Compiles
- [ ] Ran all tests
- [ ] If change impacts performance, include supporting evidence per the
[performance
document](https://github.com/stellar/stellar-core/blob/master/performance-eval/performance-eval.md)
  • Loading branch information
marta-lokhova authored Aug 7, 2024
2 parents 4554182 + a8869a9 commit 3089d1c
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 24 deletions.
30 changes: 14 additions & 16 deletions src/ledger/LedgerTxn.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -182,10 +182,10 @@ LedgerKeyMeter::canLoad(LedgerKey const& key, size_t entrySizeBytes) const
void
LedgerKeyMeter::addTxn(SorobanResources const& resources)
{
mTxReadBytes.push_back(resources.readBytes);
auto txId = mTxReadBytes.size() - 1;
TxReadBytesPtr txReadBytesPtr =
std::make_shared<uint32_t>(resources.readBytes);
auto addKeyToTxnMap = [&](auto const& key) {
mLedgerKeyToTxs[key].emplace_back(txId);
mLedgerKeyToTxReadBytes[key].emplace_back(txReadBytesPtr);
};
std::for_each(resources.footprint.readOnly.begin(),
resources.footprint.readOnly.end(), addKeyToTxnMap);
Expand All @@ -197,8 +197,8 @@ void
LedgerKeyMeter::updateReadQuotasForKey(LedgerKey const& key,
size_t entrySizeBytes)
{
auto iter = mLedgerKeyToTxs.find(key);
if (iter == mLedgerKeyToTxs.end())
auto iter = mLedgerKeyToTxReadBytes.find(key);
if (iter == mLedgerKeyToTxReadBytes.end())
{
// Key does not belong to the footprint of any transaction.
// Ensure this is not a soroban key as they should always be metered.
Expand All @@ -208,17 +208,16 @@ LedgerKeyMeter::updateReadQuotasForKey(LedgerKey const& key,
}
// Update the read quota for every transaction containing this key.
bool exceedsQuotaForAllTxns = true;
for (auto txn : iter->second)
for (TxReadBytesPtr txReadBytesPtr : iter->second)
{
auto& quota = mTxReadBytes.at(txn);
if (quota < entrySizeBytes)
if (*txReadBytesPtr < entrySizeBytes)
{
quota = 0;
*txReadBytesPtr = 0;
}
else
{
exceedsQuotaForAllTxns = false;
quota -= entrySizeBytes;
*txReadBytesPtr -= entrySizeBytes;
}
}
if (exceedsQuotaForAllTxns)
Expand All @@ -230,8 +229,8 @@ LedgerKeyMeter::updateReadQuotasForKey(LedgerKey const& key,
uint32_t
LedgerKeyMeter::maxReadQuotaForKey(LedgerKey const& key) const
{
auto iter = mLedgerKeyToTxs.find(key);
if (iter == mLedgerKeyToTxs.end())
auto iter = mLedgerKeyToTxReadBytes.find(key);
if (iter == mLedgerKeyToTxReadBytes.end())
{
// Key does not belong to the footprint of any transaction,
// therefore it is not quota-limited.
Expand All @@ -240,10 +239,9 @@ LedgerKeyMeter::maxReadQuotaForKey(LedgerKey const& key) const
key.type() != CONTRACT_DATA);
return std::numeric_limits<uint32_t>::max();
}
return std::reduce(iter->second.begin(), iter->second.end(), 0,
[&](uint32_t maxReadQuota, size_t const txn) {
return std::max(maxReadQuota, mTxReadBytes.at(txn));
});
return **std::max_element(
iter->second.begin(), iter->second.end(),
[&](TxReadBytesPtr a, TxReadBytesPtr b) { return *a < *b; });
}

bool
Expand Down
13 changes: 5 additions & 8 deletions src/ledger/LedgerTxn.h
Original file line number Diff line number Diff line change
Expand Up @@ -350,14 +350,11 @@ class LedgerKeyMeter : public NonMovableOrCopyable
private:
// Returns the maximum read quota across all transactions with this key.
uint32_t maxReadQuotaForKey(LedgerKey const& key) const;

// Stores the read quota for each transaction.
std::vector<uint32_t> mTxReadBytes{};
// Stores the keys that each transaction will read. i.e.
// mLedgerKeyToTxs[key] is a vector containing the indices of
// mTxReadBytes corresponding to the transactions which have
// the key in their footprint.
UnorderedMap<LedgerKey, std::vector<size_t>> mLedgerKeyToTxs{};
using TxReadBytesPtr = std::shared_ptr<uint32_t>;
// Stores a mapping from keys to a vector of pointers to the read bytes
// of the transactions that will read the keys.
UnorderedMap<LedgerKey, std::vector<TxReadBytesPtr>>
mLedgerKeyToTxReadBytes{};
// Stores the keys that were not loaded due to insufficient read quota.
LedgerKeySet mNotLoadedKeys{};
};
Expand Down

0 comments on commit 3089d1c

Please sign in to comment.