mirror of
https://github.com/mikecarper/MeshCore.git
synced 2026-10-23 00:41:18 +00:00
Compact flood filter persistence
This commit is contained in:
1 parent
177eb06745
commit
9e4d246ac6
3 files changed
+61
-7
No files matched your search
@@ -5001,7 +5001,8 @@ bool MyMesh::loadFloodPacketFilters() {
|
||||
bool version_7 = success && memcmp(magic, "FPF7", sizeof(magic)) == 0;
|
||||
success = (version_6 || version_7)
|
||||
&& file.read(&count, sizeof(count)) == sizeof(count)
|
||||
&& count <= FLOOD_PACKET_FILTER_SLOTS;
|
||||
&& FloodFilterPolicy::forwardPersistenceCountSupported(
|
||||
count, FLOOD_PACKET_FILTER_SLOTS);
|
||||
|
||||
for (int i = 0; success && i < count; i++) {
|
||||
uint8_t active = 0;
|
||||
@@ -5762,14 +5763,13 @@ bool MyMesh::saveFloodPacketFilters(bool empty_scope_phase,
|
||||
};
|
||||
|
||||
const uint8_t magic[4] = {'F', 'P', 'F', '7'};
|
||||
uint8_t count = FLOOD_PACKET_FILTER_SLOTS;
|
||||
const uint8_t count = FloodFilterPolicy::forwardPersistenceCount(
|
||||
flood_packet_filters, FLOOD_PACKET_FILTER_SLOTS,
|
||||
empty_forward_phase);
|
||||
bool success = writeExact(magic, sizeof(magic))
|
||||
&& writeExact(&count, sizeof(count));
|
||||
FloodPacketFilterEntry empty_entry;
|
||||
memset(&empty_entry, 0, sizeof(empty_entry));
|
||||
for (int i = 0; success && i < FLOOD_PACKET_FILTER_SLOTS; i++) {
|
||||
const auto& entry = empty_forward_phase
|
||||
? empty_entry : flood_packet_filters[i];
|
||||
for (int i = 0; success && i < count; i++) {
|
||||
const auto& entry = flood_packet_filters[i];
|
||||
uint8_t active = entry.active ? 1 : 0;
|
||||
uint8_t suspend_on_temp_radio = entry.suspend_on_temp_radio ? 1 : 0;
|
||||
uint8_t match_blacklisted_path = entry.match_blacklisted_path ? 1 : 0;
|
||||
|
||||
@@ -40,6 +40,25 @@ enum ChannelScopeGate {
|
||||
CHANNEL_SCOPE_REQUIRED_REJECTED,
|
||||
};
|
||||
|
||||
// Persist only through the highest occupied forward-rule slot. The on-disk
|
||||
// formats are dense, so inactive holes before that slot must remain present,
|
||||
// while the usually-large inactive tail need not consume LittleFS space.
|
||||
// `empty_forward_phase` deliberately wins over the live table for atomic
|
||||
// phase-clearing transactions.
|
||||
template<typename Entry>
|
||||
inline uint8_t forwardPersistenceCount(const Entry entries[],
|
||||
uint8_t slot_count,
|
||||
bool empty_forward_phase) {
|
||||
if (empty_forward_phase || entries == NULL) return 0;
|
||||
while (slot_count > 0 && !entries[slot_count - 1].active) slot_count--;
|
||||
return slot_count;
|
||||
}
|
||||
|
||||
inline bool forwardPersistenceCountSupported(uint8_t count,
|
||||
uint8_t slot_count) {
|
||||
return count <= slot_count;
|
||||
}
|
||||
|
||||
inline ChannelScopeGate channelScopeGate(bool table_active,
|
||||
bool is_group_channel_packet,
|
||||
bool channel_requires_scope,
|
||||
|
||||
@@ -3,6 +3,41 @@
|
||||
#include <helpers/FloodFilterPolicy.h>
|
||||
#include <helpers/RegionNameUtils.h>
|
||||
|
||||
struct FloodPersistenceRow {
|
||||
bool active;
|
||||
};
|
||||
|
||||
TEST(FloodFilterPersistence, DefaultRowsTrimTheInactiveTail) {
|
||||
FloodPersistenceRow rows[63] = {};
|
||||
rows[0].active = true;
|
||||
rows[1].active = true;
|
||||
|
||||
EXPECT_EQ(2, FloodFilterPolicy::forwardPersistenceCount(
|
||||
rows, 63, false));
|
||||
}
|
||||
|
||||
TEST(FloodFilterPersistence, SparseHighSlotPreservesEveryEarlierPosition) {
|
||||
FloodPersistenceRow rows[63] = {};
|
||||
rows[0].active = true;
|
||||
rows[47].active = true;
|
||||
|
||||
EXPECT_EQ(48, FloodFilterPolicy::forwardPersistenceCount(
|
||||
rows, 63, false));
|
||||
}
|
||||
|
||||
TEST(FloodFilterPersistence, EmptyForwardPhaseSerializesNoRows) {
|
||||
FloodPersistenceRow rows[63] = {};
|
||||
rows[62].active = true;
|
||||
|
||||
EXPECT_EQ(0, FloodFilterPolicy::forwardPersistenceCount(
|
||||
rows, 63, true));
|
||||
}
|
||||
|
||||
TEST(FloodFilterPersistence, OldFullCountRemainsLoadCompatible) {
|
||||
EXPECT_TRUE(FloodFilterPolicy::forwardPersistenceCountSupported(63, 63));
|
||||
EXPECT_FALSE(FloodFilterPolicy::forwardPersistenceCountSupported(64, 63));
|
||||
}
|
||||
|
||||
static mesh::Packet makeFloodPacket(uint8_t hash_size,
|
||||
const uint8_t* path,
|
||||
uint8_t path_hops) {
|
||||
|
||||
Reference in new issue
Block a user