Files
rippled/include/xrpl/ledger/PendingSaves.h
2026-07-13 10:40:40 +00:00

134 lines
2.9 KiB
C++

#pragma once
#include <xrpl/protocol/Protocol.h>
#include <condition_variable>
#include <map>
#include <mutex>
namespace xrpl {
/**
* Keeps track of which ledgers haven't been fully saved.
*
* During the ledger building process this collection will keep
* track of those ledgers that are being built but have not yet
* been completely written.
*/
class PendingSaves
{
private:
std::mutex mutable mutex_;
std::map<LedgerIndex, bool> map_;
std::condition_variable await_;
public:
/**
* Start working on a ledger
*
* This is called prior to updating the SQLite indexes.
*
* @return 'true' if work should be done
*/
bool
startWork(LedgerIndex seq)
{
std::scoped_lock const lock(mutex_);
auto it = map_.find(seq);
if ((it == map_.end()) || it->second)
{
// Work done or another thread is doing it
return false;
}
it->second = true;
return true;
}
/**
* Finish working on a ledger
*
* This is called after updating the SQLite indexes.
* The tracking of the work in progress is removed and
* threads awaiting completion are notified.
*/
void
finishWork(LedgerIndex seq)
{
std::scoped_lock const lock(mutex_);
map_.erase(seq);
await_.notify_all();
}
/**
* Return `true` if a ledger is in the progress of being saved.
*/
bool
pending(LedgerIndex seq)
{
std::scoped_lock const lock(mutex_);
return map_.contains(seq);
}
/**
* Check if a ledger should be dispatched
*
* Called to determine whether work should be done or
* dispatched. If work is already in progress and the
* call is synchronous, wait for work to be completed.
*
* @return 'true' if work should be done or dispatched
*/
bool
shouldWork(LedgerIndex seq, bool isSynchronous)
{
std::unique_lock<std::mutex> lock(mutex_);
do
{
auto it = map_.find(seq);
if (it == map_.end())
{
map_.emplace(seq, false);
return true;
}
if (!isSynchronous)
{
// Already dispatched
return false;
}
if (!it->second)
{
// Scheduled, but not dispatched
return true;
}
// Already in progress, just need to wait
await_.wait(lock);
} while (true);
}
/**
* Get a snapshot of the pending saves
*
* Each entry in the returned map corresponds to a ledger
* that is in progress or dispatched. The boolean indicates
* whether work is currently in progress.
*/
std::map<LedgerIndex, bool>
getSnapshot() const
{
std::scoped_lock const lock(mutex_);
return map_;
}
};
} // namespace xrpl