Files
rippled/include/xrpl/ledger/PendingSaves.h
2026-04-17 13:30:52 +00:00

127 lines
2.8 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::lock_guard 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::lock_guard 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::lock_guard 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::lock_guard const lock(mutex_);
return map_;
}
};
} // namespace xrpl