Smaller dictionary. Realtime text computation
This commit is contained in:
@@ -54,34 +54,19 @@ QList<CodewordPair> JSC::compress(QString text){
|
||||
|
||||
foreach(QString w, text.split(" ", QString::SkipEmptyParts)){
|
||||
bool ok = false;
|
||||
auto index = lookup(w, &ok);
|
||||
if(ok){
|
||||
// cool, we found the word...
|
||||
out.append({ codeword(index, true, b, s, c), (quint32)w.length() + 1 /* for the space that follows */ });
|
||||
} else {
|
||||
// hmm. no dice. let's go for a prefix match
|
||||
|
||||
while(!w.isEmpty()){
|
||||
bool hasPrefix = false;
|
||||
auto d = w.toLatin1().data();
|
||||
for(quint32 i = 0; i < JSC::size; i++){
|
||||
quint32 len = JSC::list[i].size;
|
||||
if(strncmp(d, JSC::list[i].str, len) == 0){
|
||||
w = QString(w.mid(len));
|
||||
// this does both prefix and full match lookup
|
||||
auto index = lookup(w, &ok);
|
||||
if(!ok){
|
||||
break;
|
||||
}
|
||||
|
||||
auto t = JSC::map[index];
|
||||
w = QString(w.mid(t.size));
|
||||
|
||||
auto index = JSC::list[i].index;
|
||||
bool isLast = w.isEmpty();
|
||||
out.append({ codeword(index, isLast, b, s, c), len + (isLast ? 1 : 0) /* for the space that follows */});
|
||||
hasPrefix = true;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!hasPrefix){
|
||||
// no match...SOL
|
||||
break;
|
||||
}
|
||||
}
|
||||
out.append({ codeword(index, isLast, b, s, c), (quint32)t.size + (isLast ? 1 : 0) /* for the space that follows */});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,10 +135,47 @@ quint32 JSC::lookup(QString w, bool * ok){
|
||||
}
|
||||
|
||||
quint32 JSC::lookup(char const* b, bool *ok){
|
||||
for(quint32 i = 0; i < JSC::size; i++){
|
||||
if(strcmp(b, JSC::map[i].str) == 0){
|
||||
quint32 index = 0;
|
||||
quint32 count = 0;
|
||||
bool found = false;
|
||||
|
||||
// first find prefix match to jump into the list faster
|
||||
for(quint32 i = 0; i < JSC::prefixSize; i++){
|
||||
// skip obvious non-prefixes...
|
||||
if(b[0] != JSC::prefix[i].str[0]){
|
||||
continue;
|
||||
}
|
||||
|
||||
// ok, we found one... let's end early for single char strings.
|
||||
if(JSC::prefix[i].size == 1){
|
||||
if(ok) *ok = true;
|
||||
return i;
|
||||
return JSC::list[JSC::prefix[i].index].index;
|
||||
}
|
||||
|
||||
// otherwise, keep track of the first index in the list and the number of elements
|
||||
index = JSC::prefix[i].index;
|
||||
count = JSC::prefix[i].size;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
||||
// no prefix found... no lookup
|
||||
if(!found){
|
||||
if(ok) *ok = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// now that we have the first index in the list, let's just iterate through the list, comparing words along the way
|
||||
for(quint32 i = index; i < index + count; i++){
|
||||
// if we're no longer a prefix match, end.
|
||||
if(b[0] != JSC::list[i].str[0]){
|
||||
break;
|
||||
}
|
||||
|
||||
quint32 len = JSC::list[i].size;
|
||||
if(strncmp(b, JSC::list[i].str, len) == 0){
|
||||
if(ok) *ok = true;
|
||||
return JSC::list[i].index;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -35,9 +35,12 @@ public:
|
||||
static quint32 lookup(QString w, bool *ok);
|
||||
static quint32 lookup(char const* b, bool *ok);
|
||||
|
||||
static const quint32 size = 524288;
|
||||
static const Tuple map[524288];
|
||||
static const Tuple list[524288];
|
||||
static const quint32 size = 262144;
|
||||
static const Tuple map[262144];
|
||||
static const Tuple list[262144];
|
||||
|
||||
static const quint32 prefixSize = 68;
|
||||
static const Tuple prefix[68];
|
||||
};
|
||||
|
||||
#endif // JSC_H
|
||||
|
||||
+262198
-524271
File diff suppressed because it is too large
Load Diff
+260711
-522855
File diff suppressed because it is too large
Load Diff
+30
-43
@@ -549,6 +549,7 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
|
||||
m_i3bit {0},
|
||||
m_manual {&m_network_manager},
|
||||
m_txFrameCount {0},
|
||||
m_txTextDirty {false},
|
||||
m_previousFreq {0}
|
||||
{
|
||||
ui->setupUi(this);
|
||||
@@ -6162,7 +6163,7 @@ bool MainWindow::prepareNextMessageFrame()
|
||||
ui->nextFreeTextMsg->clear();
|
||||
|
||||
// TODO: jsherer - this button thing is duplicated in two places :(
|
||||
ui->startTxButton->setText(QString("Send"));
|
||||
//ui->startTxButton->setText(QString("Send"));
|
||||
|
||||
return false;
|
||||
} else {
|
||||
@@ -6179,7 +6180,7 @@ bool MainWindow::prepareNextMessageFrame()
|
||||
}
|
||||
|
||||
// TODO: jsherer - this button thing is duplicated in two places :(
|
||||
ui->startTxButton->setText(QString("Sending (%1/%2)").arg(sent).arg(count));
|
||||
//ui->startTxButton->setText(QString("Sending (%1/%2)").arg(sent).arg(count));
|
||||
|
||||
if(ui->beaconButton->isChecked()){
|
||||
// bump beacon
|
||||
@@ -8735,57 +8736,20 @@ void MainWindow::updateButtonDisplay(){
|
||||
ui->queryButton->setText(emptyCallsign ? "Directed" : QString("Directed to %1").arg(selectedCallsign));
|
||||
ui->startTxButton->setDisabled(isTransmitting || emptyText || invalidSelcal);
|
||||
|
||||
#if 0
|
||||
// update transmit button
|
||||
if(isTransmitting){
|
||||
int count = m_txFrameCount;
|
||||
int sent = count - m_txFrameQueue.count();
|
||||
ui->startTxButton->setText(m_tune ? "Tuning" : QString("Sending (%1/%2)").arg(sent).arg(count));
|
||||
ui->startTxButton->setEnabled(false);
|
||||
} else {
|
||||
if(ui->extFreeTextMsgEdit->toPlainText().isEmpty()){
|
||||
m_txFrameCountEstimate = 0;
|
||||
}
|
||||
ui->startTxButton->setText(m_txFrameCountEstimate <= 0 ? QString("Send") : QString("Send (%1)").arg(m_txFrameCountEstimate));
|
||||
ui->startTxButton->setEnabled(m_txFrameCountEstimate > 0 && ensureSelcalCallsignSelected(false));
|
||||
}
|
||||
|
||||
if(m_txTextDirty){
|
||||
// debounce frame and word count
|
||||
if(m_txTextDirtyDebounce.isActive()){
|
||||
m_txTextDirtyDebounce.stop();
|
||||
}
|
||||
m_txTextDirtyDebounce.start(150);
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
auto text = ui->extFreeTextMsgEdit->toPlainText();
|
||||
bool hasText = !text.isEmpty();
|
||||
|
||||
// update the estimate immediately if we know that the text box is empty...
|
||||
if(hasText){
|
||||
countMessageFrames(text);
|
||||
} else {
|
||||
updateFrameCountEstimate(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
// schedule word count update
|
||||
if(hasText && m_txTextDirty && (m_txTextDirtyLastText != ui->extFreeTextMsgEdit->toPlainText() || m_txTextDirtyLastSelectedCall != selectedCallsign)){
|
||||
|
||||
if(m_txTextDirtyDebounce.isActive()){
|
||||
m_txTextDirtyDebounce.stop();
|
||||
}
|
||||
m_txTextDirtyDebounce.start(100);
|
||||
m_txTextDirty = false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#define USE_SYNC_FRAME_COUNT 1
|
||||
|
||||
void MainWindow::refreshTextDisplay(){
|
||||
auto text = ui->extFreeTextMsgEdit->toPlainText();
|
||||
m_txTextDirtyLastText = text;
|
||||
|
||||
#if USE_SYNC_FRAME_COUNT
|
||||
auto frames = buildMessageFrames(text);
|
||||
@@ -8798,9 +8762,18 @@ void MainWindow::refreshTextDisplay(){
|
||||
textList.append(dt.message());
|
||||
}
|
||||
|
||||
updateTextStatsDisplay(textList.join(""), m_txFrameCountEstimate);
|
||||
auto transmitText = textList.join("");
|
||||
auto count = frames.length();
|
||||
|
||||
// ugh...i hate these globals
|
||||
m_txTextDirtyLastSelectedCall = callsignSelected(true);
|
||||
m_txTextDirtyLastText = text;
|
||||
m_txFrameCountEstimate = count;
|
||||
m_txTextDirty = false;
|
||||
|
||||
updateTextStatsDisplay(transmitText, count);
|
||||
updateTxButtonDisplay();
|
||||
|
||||
m_txFrameCountEstimate = frames.length();
|
||||
#else
|
||||
// prepare selected callsign for directed message
|
||||
QString selectedCall = callsignSelected();
|
||||
@@ -8832,6 +8805,7 @@ void MainWindow::refreshTextDisplay(){
|
||||
|
||||
updateFrameCountEstimate(frames.length());
|
||||
updateTextStatsDisplay(textList.join(""), frames.length());
|
||||
m_txTextDirty = false;
|
||||
|
||||
});
|
||||
t->start();
|
||||
@@ -8851,6 +8825,19 @@ void MainWindow::updateTextStatsDisplay(QString text, int count){
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::updateTxButtonDisplay(){
|
||||
// update transmit button
|
||||
if(m_tune || m_transmitting || m_txFrameCount > 0){
|
||||
int count = m_txFrameCount;
|
||||
int sent = count - m_txFrameQueue.count();
|
||||
ui->startTxButton->setText(m_tune ? "Tuning" : QString("Sending (%1/%2)").arg(sent).arg(count));
|
||||
ui->startTxButton->setEnabled(false);
|
||||
} else {
|
||||
ui->startTxButton->setText(m_txFrameCountEstimate <= 0 ? QString("Send") : QString("Send (%1)").arg(m_txFrameCountEstimate));
|
||||
ui->startTxButton->setEnabled(m_txFrameCountEstimate > 0 && ensureSelcalCallsignSelected(false));
|
||||
}
|
||||
}
|
||||
|
||||
QString MainWindow::callsignSelected(bool useInputText){
|
||||
if(!ui->tableWidgetCalls->selectedItems().isEmpty()){
|
||||
auto selectedCalls = ui->tableWidgetCalls->selectedItems();
|
||||
|
||||
@@ -885,6 +885,7 @@ private:
|
||||
void updateButtonDisplay();
|
||||
void updateFrameCountEstimate(int count);
|
||||
void updateTextStatsDisplay(QString text, int count);
|
||||
void updateTxButtonDisplay();
|
||||
bool isMyCallIncluded(QString const &text);
|
||||
bool isAllCallIncluded(QString const &text);
|
||||
QString callsignSelected(bool useInputText=false);
|
||||
|
||||
Reference in New Issue
Block a user