mirror of
https://github.com/XRPLF/clio.git
synced 2025-11-21 20:25:52 +00:00
optimized ledger_data
This commit is contained in:
@@ -244,6 +244,7 @@ BackendInterface::fetchLedgerPage(
|
|||||||
std::optional<ripple::uint256> const& cursor,
|
std::optional<ripple::uint256> const& cursor,
|
||||||
std::uint32_t const ledgerSequence,
|
std::uint32_t const ledgerSequence,
|
||||||
std::uint32_t const limit,
|
std::uint32_t const limit,
|
||||||
|
bool outOfOrder,
|
||||||
boost::asio::yield_context& yield) const
|
boost::asio::yield_context& yield) const
|
||||||
{
|
{
|
||||||
LedgerPage page;
|
LedgerPage page;
|
||||||
@@ -254,8 +255,8 @@ BackendInterface::fetchLedgerPage(
|
|||||||
ripple::uint256 const& curCursor = keys.size() ? keys.back()
|
ripple::uint256 const& curCursor = keys.size() ? keys.back()
|
||||||
: cursor ? *cursor
|
: cursor ? *cursor
|
||||||
: firstKey;
|
: firstKey;
|
||||||
auto succ = fetchSuccessorKey(curCursor, ledgerSequence, yield);
|
uint32_t seq = outOfOrder ? range->maxSequence : ledgerSequence;
|
||||||
|
auto succ = fetchSuccessorKey(curCursor, seq, yield);
|
||||||
if (!succ)
|
if (!succ)
|
||||||
break;
|
break;
|
||||||
BOOST_LOG_TRIVIAL(trace) << ripple::strHex(*succ);
|
BOOST_LOG_TRIVIAL(trace) << ripple::strHex(*succ);
|
||||||
|
|||||||
@@ -217,6 +217,7 @@ public:
|
|||||||
std::optional<ripple::uint256> const& cursor,
|
std::optional<ripple::uint256> const& cursor,
|
||||||
std::uint32_t const ledgerSequence,
|
std::uint32_t const ledgerSequence,
|
||||||
std::uint32_t const limit,
|
std::uint32_t const limit,
|
||||||
|
bool outOfOrder,
|
||||||
boost::asio::yield_context& yield) const;
|
boost::asio::yield_context& yield) const;
|
||||||
|
|
||||||
// Fetches the successor to key/index
|
// Fetches the successor to key/index
|
||||||
|
|||||||
@@ -45,12 +45,30 @@ doLedgerData(Context const& context)
|
|||||||
|
|
||||||
limit = boost::json::value_to<int>(request.at("limit"));
|
limit = boost::json::value_to<int>(request.at("limit"));
|
||||||
}
|
}
|
||||||
|
bool outOfOrder = false;
|
||||||
|
if (request.contains("out_of_order"))
|
||||||
|
{
|
||||||
|
if (!request.at("out_of_order").is_bool())
|
||||||
|
return Status{Error::rpcINVALID_PARAMS, "binaryFlagNotBool"};
|
||||||
|
outOfOrder = request.at("out_of_order").as_bool();
|
||||||
|
}
|
||||||
|
|
||||||
std::optional<ripple::uint256> cursor;
|
std::optional<ripple::uint256> cursor;
|
||||||
|
std::optional<uint32_t> diffCursor;
|
||||||
if (request.contains("marker"))
|
if (request.contains("marker"))
|
||||||
{
|
{
|
||||||
if (!request.at("marker").is_string())
|
if (!request.at("marker").is_string())
|
||||||
|
{
|
||||||
|
if (outOfOrder)
|
||||||
|
{
|
||||||
|
if (!request.at("marker").is_int64())
|
||||||
|
return Status{
|
||||||
|
Error::rpcINVALID_PARAMS, "markerNotStringOrInt"};
|
||||||
|
diffCursor = value_to<uint32_t>(request.at("marker"));
|
||||||
|
}
|
||||||
|
else
|
||||||
return Status{Error::rpcINVALID_PARAMS, "markerNotString"};
|
return Status{Error::rpcINVALID_PARAMS, "markerNotString"};
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_LOG_TRIVIAL(debug) << __func__ << " : parsing marker";
|
BOOST_LOG_TRIVIAL(debug) << __func__ << " : parsing marker";
|
||||||
|
|
||||||
@@ -64,15 +82,8 @@ doLedgerData(Context const& context)
|
|||||||
return *status;
|
return *status;
|
||||||
|
|
||||||
auto lgrInfo = std::get<ripple::LedgerInfo>(v);
|
auto lgrInfo = std::get<ripple::LedgerInfo>(v);
|
||||||
|
|
||||||
Backend::LedgerPage page;
|
|
||||||
auto start = std::chrono::system_clock::now();
|
|
||||||
page = context.backend->fetchLedgerPage(
|
|
||||||
cursor, lgrInfo.seq, limit, context.yield);
|
|
||||||
|
|
||||||
auto end = std::chrono::system_clock::now();
|
|
||||||
|
|
||||||
boost::json::object header;
|
boost::json::object header;
|
||||||
|
// no cursor means this is the first call, so we return header info
|
||||||
if (!cursor)
|
if (!cursor)
|
||||||
{
|
{
|
||||||
if (binary)
|
if (binary)
|
||||||
@@ -104,23 +115,55 @@ doLedgerData(Context const& context)
|
|||||||
response["ledger"] = header;
|
response["ledger"] = header;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
response["ledger_hash"] = ripple::strHex(lgrInfo.hash);
|
response["ledger_hash"] = ripple::strHex(lgrInfo.hash);
|
||||||
response["ledger_index"] = lgrInfo.seq;
|
response["ledger_index"] = lgrInfo.seq;
|
||||||
|
|
||||||
boost::json::array objects;
|
auto start = std::chrono::system_clock::now();
|
||||||
std::vector<Backend::LedgerObject>& results = page.objects;
|
std::vector<Backend::LedgerObject> results;
|
||||||
std::optional<ripple::uint256> const& returnedCursor = page.cursor;
|
if (diffCursor)
|
||||||
|
|
||||||
if (returnedCursor)
|
|
||||||
{
|
{
|
||||||
response["marker"] = ripple::strHex(*returnedCursor);
|
assert(outOfOrder);
|
||||||
BOOST_LOG_TRIVIAL(debug)
|
auto diff =
|
||||||
<< __func__ << " cursor = " << ripple::strHex(*returnedCursor);
|
context.backend->fetchLedgerDiff(*diffCursor, context.yield);
|
||||||
|
std::vector<ripple::uint256> keys;
|
||||||
|
for (auto&& [key, object] : diff)
|
||||||
|
{
|
||||||
|
if (!object.size())
|
||||||
|
{
|
||||||
|
keys.push_back(std::move(key));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
auto objs = context.backend->fetchLedgerObjects(
|
||||||
|
keys, lgrInfo.seq, context.yield);
|
||||||
|
for (size_t i = 0; i < objs.size(); ++i)
|
||||||
|
{
|
||||||
|
auto&& obj = objs[i];
|
||||||
|
results.push_back({std::move(keys[i]), std::move(obj)});
|
||||||
|
}
|
||||||
|
if (*diffCursor > lgrInfo.seq)
|
||||||
|
response["marker"] = *diffCursor - 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto page = context.backend->fetchLedgerPage(
|
||||||
|
cursor, lgrInfo.seq, limit, outOfOrder, context.yield);
|
||||||
|
results = std::move(page.objects);
|
||||||
|
if (page.cursor)
|
||||||
|
response["marker"] = ripple::strHex(*(page.cursor));
|
||||||
|
else if (outOfOrder)
|
||||||
|
response["marker"] =
|
||||||
|
context.backend->fetchLedgerRange()->maxSequence;
|
||||||
|
}
|
||||||
|
auto end = std::chrono::system_clock::now();
|
||||||
|
|
||||||
|
auto time =
|
||||||
|
std::chrono::duration_cast<std::chrono::microseconds>(end - start)
|
||||||
|
.count();
|
||||||
|
|
||||||
BOOST_LOG_TRIVIAL(debug)
|
BOOST_LOG_TRIVIAL(debug)
|
||||||
<< __func__ << " number of results = " << results.size();
|
<< __func__ << " number of results = " << results.size()
|
||||||
|
<< " fetched in " << time << "microseconds";
|
||||||
|
boost::json::array objects;
|
||||||
for (auto const& [key, object] : results)
|
for (auto const& [key, object] : results)
|
||||||
{
|
{
|
||||||
ripple::STLedgerEntry sle{
|
ripple::STLedgerEntry sle{
|
||||||
|
|||||||
Reference in New Issue
Block a user