NodeDB::isFromOrToFavoritedNode: skip search for NODENUM_BROADCAST; one-pass search and early exit

This commit is contained in:
Mike Robbins 2025-09-07 21:08:00 -07:00
parent c63102a312
commit b768860866

View File

@ -1772,7 +1772,14 @@ void NodeDB::set_favorite(bool is_favorite, uint32_t nodeId)
bool NodeDB::isFavorite(uint32_t nodeId)
{
// returns true if nodeId is_favorite; false if not or not found
// NODENUM_BROADCAST will never be in the DB
if (nodeId == NODENUM_BROADCAST)
return false;
meshtastic_NodeInfoLite *lite = getMeshNode(nodeId);
if (lite) {
return lite->is_favorite;
}
@ -1781,7 +1788,45 @@ bool NodeDB::isFavorite(uint32_t nodeId)
bool NodeDB::isFromOrToFavoritedNode(const meshtastic_MeshPacket &p)
{
return isFavorite(p.from) || isFavorite(p.to);
// This method is logically equivalent to:
// return isFavorite(p.from) || isFavorite(p.to);
// but is more efficient by:
// 1. doing only one pass through the database, instead of two
// 2. exiting early when a favorite is found, or if both from and to have been seen
if (p.to == NODENUM_BROADCAST)
return isFavorite(p.from); // we never store NODENUM_BROADCAST in the DB, so we only need to check p.from
meshtastic_NodeInfoLite *lite = NULL;
bool seenFrom = false;
bool seenTo = false;
for (int i = 0; i < numMeshNodes; i++) {
lite = &meshNodes->at(i);
if (lite->num == p.from) {
if (lite->is_favorite)
return true;
seenFrom = true;
}
if (lite->num == p.to) {
if (lite->is_favorite)
return true;
seenTo = true;
}
if (seenFrom && seenTo)
return false; // we've seen both, and neither is a favorite, so we can stop searching early
// Note: if we knew that sortMeshDB was always called after any change to is_favorite, we could exit early after searching
// all favorited nodes first.
}
return false;
}
void NodeDB::pause_sort(bool paused)