GXS: one SQL query per group when no message filter is requested

RsGxsDataAccess::getMsgData() always ran the request through getMsgIdList(),
which walks every message meta of the group and returns the explicit list of
matching message ids. That list was then handed to RsDataService, whose
retrieveNxsMsgs() has two paths: a single "WHERE grpId=..." query when the id
set is empty, and one prepared query per message otherwise.

Since a request for a whole group carries an empty id set precisely to mean
"all messages", expanding it into 6400 explicit ids meant the fast path was
never taken when opening a channel: the store issued 6400 separate
sqlite3_prepare_v2 + step + finalize cycles against an encrypted database,
plus a full preliminary pass over the metas that produced nothing the caller
did not already know.

When none of mStatusMask, mMsgFlagMask, MSG_LATEST, MSG_ORIGMSG or MSG_THREAD
is set, no filtering can occur, so pass the request through untouched. The
resulting message set is identical, the meta pass disappears, and loading a
whole group collapses to a single SQL query.

Requests that do filter are unaffected and keep the previous path.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
jolavillette 2026-07-27 10:51:57 +02:00
parent 0442e59411
commit f9b90cb26b

View File

@ -1006,6 +1006,21 @@ bool RsGxsDataAccess::getMsgData(MsgDataReq* req)
const RsTokReqOptions& opts(req->Options);
// When no filtering at all is requested, resolving the message ids is pure
// overhead: it walks every meta of the group only to hand back the set the
// request already implies. Worse, it turns a request meaning "all messages
// of this group" (empty id set) into an explicit id list, which forces the
// data store to issue one SQL query per message instead of a single one.
// Opening a channel with a few thousand posts is exactly that case.
if( !opts.mStatusMask && !opts.mMsgFlagMask &&
!( opts.mOptions & ( RS_TOKREQOPT_MSG_LATEST |
RS_TOKREQOPT_MSG_ORIGMSG |
RS_TOKREQOPT_MSG_THREAD ) ) )
{
mDataStore->retrieveNxsMsgs(req->mMsgIds, req->mMsgData, true);
return true;
}
// filter based on options
getMsgIdList(req->mMsgIds, opts, msgIdOut);