From 4f39a6bd8977a3d15e7539a99060d75c9aa00e57 Mon Sep 17 00:00:00 2001 From: Abs62 Date: Thu, 8 Sep 2022 18:14:31 +0300 Subject: [PATCH] Full-text search: Optimize data transfer to articles list --- fulltextsearch.cc | 104 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 80 insertions(+), 24 deletions(-) diff --git a/fulltextsearch.cc b/fulltextsearch.cc index 311859bc..002f5f95 100644 --- a/fulltextsearch.cc +++ b/fulltextsearch.cc @@ -126,6 +126,72 @@ QString FtsIndexing::nowIndexingName() return nowIndexing; } +void addSortedHeadwords( QList< FtsHeadword > & base_list, QList< FtsHeadword > const & add_list) +{ + QList< FtsHeadword > list; + + if( add_list.isEmpty() ) + return; + + if( base_list.isEmpty() ) + { + base_list = add_list; + return; + } + + list.reserve( base_list.size() + add_list.size() ); + + QList< FtsHeadword >::iterator base_it = base_list.begin(); + QList< FtsHeadword >::const_iterator add_it = add_list.constBegin(); + + while( base_it != base_list.end() || add_it != add_list.end() ) + { + if( base_it == base_list.end() ) + { + while( add_it != add_list.end() ) + { + list.append( *add_it ); + ++add_it; + } + break; + } + + if( add_it == add_list.end() ) + { + while( base_it != base_list.end() ) + { + list.append( *base_it ); + ++base_it; + } + break; + } + + if( *add_it < *base_it ) + { + list.append( *add_it ); + ++add_it; + } + else if( *add_it == *base_it ) + { + base_it->dictIDs.append( add_it->dictIDs ); + for( QStringList::const_iterator itr = add_it->foundHiliteRegExps.constBegin(); + itr != add_it->foundHiliteRegExps.constEnd(); ++itr ) + { + if( !base_it->foundHiliteRegExps.contains( *itr ) ) + base_it->foundHiliteRegExps.append( *itr ); + } + ++add_it; + } + else + { + list.append( *base_it ); + ++base_it; + } + } + + base_list.swap( list ); +} + FullTextSearchDialog::FullTextSearchDialog( QWidget * parent, Config::Class & cfg_, std::vector< sptr< Dictionary::Class > > const & dictionaries_, @@ -405,6 +471,7 @@ void FullTextSearchDialog::accept() void FullTextSearchDialog::searchReqFinished() { + QList< FtsHeadword > allHeadwords; while ( searchReqs.size() ) { std::list< sptr< Dictionary::DataRequest > >::iterator it; @@ -421,13 +488,14 @@ void FullTextSearchDialog::searchReqFinished() QList< FtsHeadword > * headwords; if( (unsigned)(*it)->dataSize() >= sizeof( headwords ) ) { + QList< FtsHeadword > hws; try { (*it)->getDataSlice( 0, sizeof( headwords ), &headwords ); - model->addResults( QModelIndex(), *headwords ); + hws.swap( *headwords ); + std::sort( hws.begin(), hws.end() ); delete headwords; - ui.articlesFoundLabel->setText( tr( "Articles found: " ) - + QString::number( results.size() ) ); + addSortedHeadwords( allHeadwords, hws ); } catch( std::exception & e ) { @@ -449,6 +517,14 @@ void FullTextSearchDialog::searchReqFinished() else break; } + + if( !allHeadwords.isEmpty() ) + { + model->addResults( QModelIndex(), allHeadwords ); + ui.articlesFoundLabel->setText( tr( "Articles found: " ) + + QString::number( results.size() ) ); + } + if ( searchReqs.empty() ) { ui.searchProgressBar->hide(); @@ -608,27 +684,7 @@ void HeadwordsListModel::addResults(const QModelIndex & parent, QList< FtsHeadwo Q_UNUSED( parent ); beginResetModel(); - QList< FtsHeadword > temp; - - for( int x = 0; x < hws.length(); x++ ) - { - QList< FtsHeadword >::iterator it = std::lower_bound( headwords.begin(), headwords.end(), hws.at( x ) ); - if( it != headwords.end() && *it == hws.at( x ) ) - { - it->dictIDs.push_back( hws.at( x ).dictIDs.front() ); - for( QStringList::const_iterator itr = it->foundHiliteRegExps.constBegin(); - itr != it->foundHiliteRegExps.constEnd(); ++itr ) - { - if( !it->foundHiliteRegExps.contains( *itr ) ) - it->foundHiliteRegExps.append( *itr ); - } - } - else - temp.append( hws.at( x ) ); - } - - headwords.append( temp ); - std::sort( headwords.begin(), headwords.end() ); + addSortedHeadwords( headwords, hws ); endResetModel(); emit contentChanged();