mirror of
https://github.com/mikecarper/MeshCore.git
synced 2026-09-26 21:07:56 +00:00
Add sorting functions for neighbour information in MyMesh and optimize MQTTBridge for memory efficiency
- Introduced comparison functions for sorting neighbours by timestamp and signal strength in MyMesh. - Implemented early exit conditions in MQTTBridge to improve processing efficiency when no neighbours are present. - Enhanced MQTTBridge to optimize memory usage by adjusting MQTT client configurations and implementing memory pressure checks. - Reduced processing limits in MQTTBridge to maintain responsiveness and prevent blocking during packet handling.
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
#include "MyMesh.h"
|
||||
#include <algorithm>
|
||||
#include <stdlib.h> // for qsort()
|
||||
|
||||
/* ------------------------------ Config -------------------------------- */
|
||||
|
||||
@@ -139,6 +140,39 @@ uint8_t MyMesh::handleLoginReq(const mesh::Identity& sender, const uint8_t* secr
|
||||
return 13; // reply length
|
||||
}
|
||||
|
||||
// Comparison functions for qsort() - defined at file scope to avoid heap allocations
|
||||
static int cmp_neighbours_newest_to_oldest(const void* a, const void* b) {
|
||||
const NeighbourInfo* na = *(const NeighbourInfo**)a;
|
||||
const NeighbourInfo* nb = *(const NeighbourInfo**)b;
|
||||
if (nb->heard_timestamp > na->heard_timestamp) return 1;
|
||||
if (nb->heard_timestamp < na->heard_timestamp) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmp_neighbours_oldest_to_newest(const void* a, const void* b) {
|
||||
const NeighbourInfo* na = *(const NeighbourInfo**)a;
|
||||
const NeighbourInfo* nb = *(const NeighbourInfo**)b;
|
||||
if (na->heard_timestamp > nb->heard_timestamp) return 1;
|
||||
if (na->heard_timestamp < nb->heard_timestamp) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmp_neighbours_strongest_to_weakest(const void* a, const void* b) {
|
||||
const NeighbourInfo* na = *(const NeighbourInfo**)a;
|
||||
const NeighbourInfo* nb = *(const NeighbourInfo**)b;
|
||||
if (nb->snr > na->snr) return 1;
|
||||
if (nb->snr < na->snr) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmp_neighbours_weakest_to_strongest(const void* a, const void* b) {
|
||||
const NeighbourInfo* na = *(const NeighbourInfo**)a;
|
||||
const NeighbourInfo* nb = *(const NeighbourInfo**)b;
|
||||
if (na->snr > nb->snr) return 1;
|
||||
if (na->snr < nb->snr) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int MyMesh::handleRequest(ClientInfo *sender, uint32_t sender_timestamp, uint8_t *payload, size_t payload_len) {
|
||||
// uint32_t now = getRTCClock()->getCurrentTimeUnique();
|
||||
// memcpy(reply_data, &now, 4); // response packets always prefixed with timestamp
|
||||
@@ -227,42 +261,47 @@ int MyMesh::handleRequest(ClientInfo *sender, uint32_t sender_timestamp, uint8_t
|
||||
MESH_DEBUG_PRINTLN("REQ_TYPE_GET_NEIGHBOURS invalid pubkey_prefix_length=%d clamping to %d", pubkey_prefix_length, PUB_KEY_SIZE);
|
||||
}
|
||||
|
||||
// create copy of neighbours list, skipping empty entries so we can sort it separately from main list
|
||||
// Early exit if no neighbours to avoid unnecessary processing
|
||||
int16_t neighbours_count = 0;
|
||||
NeighbourInfo* sorted_neighbours[MAX_NEIGHBOURS];
|
||||
for (int i = 0; i < MAX_NEIGHBOURS; i++) {
|
||||
auto neighbour = &neighbours[i];
|
||||
if (neighbour->heard_timestamp > 0) {
|
||||
sorted_neighbours[neighbours_count] = neighbour;
|
||||
if (neighbours[i].heard_timestamp > 0) {
|
||||
neighbours_count++;
|
||||
}
|
||||
}
|
||||
|
||||
if (neighbours_count == 0) {
|
||||
// No neighbours - return minimal response
|
||||
memcpy(&reply_data[reply_offset], &neighbours_count, 2); reply_offset += 2;
|
||||
uint16_t zero = 0;
|
||||
memcpy(&reply_data[reply_offset], &zero, 2); reply_offset += 2; // results_count = 0
|
||||
return reply_offset;
|
||||
}
|
||||
|
||||
// sort neighbours based on order
|
||||
// create copy of neighbours list, skipping empty entries so we can sort it separately from main list
|
||||
NeighbourInfo* sorted_neighbours[MAX_NEIGHBOURS];
|
||||
int16_t sorted_idx = 0;
|
||||
for (int i = 0; i < MAX_NEIGHBOURS; i++) {
|
||||
auto neighbour = &neighbours[i];
|
||||
if (neighbour->heard_timestamp > 0) {
|
||||
sorted_neighbours[sorted_idx++] = neighbour;
|
||||
}
|
||||
}
|
||||
|
||||
// Sort neighbours based on order using qsort() - standard C library function
|
||||
// qsort() doesn't allocate heap memory (uses stack-based recursion) and is O(n log n)
|
||||
// This matches the pattern used elsewhere in the codebase (e.g., BaseChatMesh)
|
||||
if (order_by == 0) {
|
||||
// sort by newest to oldest
|
||||
MESH_DEBUG_PRINTLN("REQ_TYPE_GET_NEIGHBOURS sorting newest to oldest");
|
||||
std::sort(sorted_neighbours, sorted_neighbours + neighbours_count, [](const NeighbourInfo* a, const NeighbourInfo* b) {
|
||||
return a->heard_timestamp > b->heard_timestamp; // desc
|
||||
});
|
||||
qsort(sorted_neighbours, neighbours_count, sizeof(NeighbourInfo*), cmp_neighbours_newest_to_oldest);
|
||||
} else if (order_by == 1) {
|
||||
// sort by oldest to newest
|
||||
MESH_DEBUG_PRINTLN("REQ_TYPE_GET_NEIGHBOURS sorting oldest to newest");
|
||||
std::sort(sorted_neighbours, sorted_neighbours + neighbours_count, [](const NeighbourInfo* a, const NeighbourInfo* b) {
|
||||
return a->heard_timestamp < b->heard_timestamp; // asc
|
||||
});
|
||||
qsort(sorted_neighbours, neighbours_count, sizeof(NeighbourInfo*), cmp_neighbours_oldest_to_newest);
|
||||
} else if (order_by == 2) {
|
||||
// sort by strongest to weakest
|
||||
MESH_DEBUG_PRINTLN("REQ_TYPE_GET_NEIGHBOURS sorting strongest to weakest");
|
||||
std::sort(sorted_neighbours, sorted_neighbours + neighbours_count, [](const NeighbourInfo* a, const NeighbourInfo* b) {
|
||||
return a->snr > b->snr; // desc
|
||||
});
|
||||
qsort(sorted_neighbours, neighbours_count, sizeof(NeighbourInfo*), cmp_neighbours_strongest_to_weakest);
|
||||
} else if (order_by == 3) {
|
||||
// sort by weakest to strongest
|
||||
MESH_DEBUG_PRINTLN("REQ_TYPE_GET_NEIGHBOURS sorting weakest to strongest");
|
||||
std::sort(sorted_neighbours, sorted_neighbours + neighbours_count, [](const NeighbourInfo* a, const NeighbourInfo* b) {
|
||||
return a->snr < b->snr; // asc
|
||||
});
|
||||
qsort(sorted_neighbours, neighbours_count, sizeof(NeighbourInfo*), cmp_neighbours_weakest_to_strongest);
|
||||
}
|
||||
|
||||
// build results buffer
|
||||
|
||||
Reference in New Issue
Block a user