Added proper caching of message frames during dedupe with date expiration

This commit is contained in:
Jordan Sherer 2020-05-11 15:11:56 -04:00
parent a6647c548b
commit ed70ac5a1a
2 changed files with 42 additions and 17 deletions

View File

@ -4921,12 +4921,15 @@ void MainWindow::decodeDone ()
m_RxLog=0; m_RxLog=0;
m_blankLine=true; m_blankLine=true;
static int dupeClearI = 0; // cleanup old cached messages (messages > submode period old)
if(dupeClearI > 2*m_TRperiod){ for (auto it = m_messageDupeCache.begin(); it != m_messageDupeCache.end();){
m_messageDupeCache.clear(); auto cached = it.value();
dupeClearI = 0; if (cached.date.secsTo(QDateTime::currentDateTimeUtc()) > computePeriodForSubmode(cached.submode)){
it = m_messageDupeCache.erase(it);
} else {
++it;
}
} }
dupeClearI++;
decodeBusy(false); decodeBusy(false);
} }
@ -5201,26 +5204,39 @@ void MainWindow::processDecodedLine(QByteArray t){
} }
auto rawText = QString::fromUtf8 (t.constData ()).remove (QRegularExpression {"\r|\n"}); auto rawText = QString::fromUtf8 (t.constData ()).remove (QRegularExpression {"\r|\n"});
DecodedText decodedtext {rawText, "FT8" == m_mode && DecodedText decodedtext {rawText, "FT8" == m_mode &&
ui->cbVHFcontest->isChecked(), m_config.my_grid ()}; ui->cbVHFcontest->isChecked(), m_config.my_grid ()};
bool bValidFrame = decodedtext.snr() >= rxSnrThreshold(decodedtext.submode());
// dupe check // frames are also valid if they pass our dupe check (haven't seen the same frame in the past 1/2 decode period)
auto frame = decodedtext.message(); auto frame = decodedtext.message();
auto frameOffset = decodedtext.frequencyOffset(); auto frameOffset = decodedtext.frequencyOffset();
if(m_messageDupeCache.contains(frame)){ auto frameDedupeKey = QString("%1:%2").arg(decodedtext.submode()).arg(frame);
if(m_messageDupeCache.contains(frameDedupeKey)){
auto cached = m_messageDupeCache.value(frameDedupeKey);
// check to see if the time since last seen is > 1/2 decode period
auto cachedDate = cached.date;
if(cachedDate.secsTo(QDateTime::currentDateTimeUtc()) < 0.5*computePeriodForSubmode(decodedtext.submode())){
qDebug() << "duplicate frame at" << cachedDate << "using key" << frameDedupeKey;
return;
}
// check to see if the frequency is near our previous frame // check to see if the frequency is near our previous frame
auto cachedFreq = m_messageDupeCache.value(frame, 0); auto cachedFreq = cached.freq;
if(qAbs(cachedFreq - frameOffset) <= rxThreshold(decodedtext.submode())){ if(qAbs(cachedFreq - frameOffset) <= rxThreshold(decodedtext.submode())){
qDebug() << "duplicate frame from" << cachedFreq << "and" << frameOffset; qDebug() << "duplicate frame from" << cachedFreq << "and" << frameOffset << "using key" << frameDedupeKey;
bValidFrame = false; return;
} }
} else {
// cache for this decode cycle // huzzah!
m_messageDupeCache[frame] = frameOffset; // if we make it here, the cache is invalid and will be bumped when we cache the new frame below
} }
// frames are valid if they meet our minimum rx threshold for the submode
bool bValidFrame = decodedtext.snr() >= rxSnrThreshold(decodedtext.submode());
qDebug() << "valid" << bValidFrame << submodeName(decodedtext.submode()) << "decoded text" << decodedtext.message(); qDebug() << "valid" << bValidFrame << submodeName(decodedtext.submode()) << "decoded text" << decodedtext.message();
// skip if invalid // skip if invalid
@ -5228,6 +5244,9 @@ void MainWindow::processDecodedLine(QByteArray t){
return; return;
} }
// if the frame is valid, cache it!
m_messageDupeCache[frameDedupeKey] = {QDateTime::currentDateTimeUtc(), decodedtext.submode(), frameOffset};
// log valid frames to ALL.txt (and correct their timestamp format) // log valid frames to ALL.txt (and correct their timestamp format)
auto freq = dialFrequency(); auto freq = dialFrequency();

View File

@ -859,8 +859,14 @@ private:
int sz; int sz;
}; };
struct CachedFrame {
QDateTime date;
int submode;
int freq;
};
QQueue<DecodeParams> m_decoderQueue; QQueue<DecodeParams> m_decoderQueue;
QMap<QString, int> m_messageDupeCache; // message frame -> freq offset seen QMap<QString, CachedFrame> m_messageDupeCache; // message frame -> date seen, submode seen, freq offset seen
QMap<QString, QVariant> m_showColumnsCache; // table column:key -> show boolean QMap<QString, QVariant> m_showColumnsCache; // table column:key -> show boolean
QMap<QString, QVariant> m_sortCache; // table key -> sort by QMap<QString, QVariant> m_sortCache; // table key -> sort by
QPriorityQueue<PrioritizedMessage> m_txMessageQueue; // messages to be sent QPriorityQueue<PrioritizedMessage> m_txMessageQueue; // messages to be sent