[search] Make search on parallel threads. Crashes! TODO: Fix crashes and use Query.SetTerminateFlag().

This commit is contained in:
Yury Melnichek 2011-06-04 20:38:18 +02:00 committed by Alex Zolotarev
parent 864222557e
commit 8318ed200c
6 changed files with 40 additions and 14 deletions

View file

@ -12,7 +12,7 @@ namespace qt
{
SearchPanel::SearchPanel(DrawWidget * drawWidget, QWidget * parent)
: QWidget(parent), m_pDrawWidget(drawWidget)
: QWidget(parent), m_pDrawWidget(drawWidget), m_queryId(0)
{
m_pEditor = new QLineEdit(this);
connect(m_pEditor, SIGNAL(textChanged(QString const &)), this, SLOT(OnSearchTextChanged(QString const &)));
@ -32,8 +32,8 @@ SearchPanel::SearchPanel(DrawWidget * drawWidget, QWidget * parent)
setLayout(verticalLayout);
// for multithreading support
connect(this, SIGNAL(SearchResultSignal(search::Result *)),
this, SLOT(OnSearchResult(search::Result *)), Qt::QueuedConnection);
CHECK(connect(this, SIGNAL(SearchResultSignal(search::Result *, int)),
this, SLOT(OnSearchResult(search::Result *, int)), Qt::QueuedConnection), ());
setFocusPolicy(Qt::StrongFocus);
setFocusProxy(m_pEditor);
@ -51,13 +51,17 @@ SearchPanel::~SearchPanel()
ClearVector(m_results);
}
void SearchPanel::SearchResultThreadFunc(search::Result const & result)
void SearchPanel::SearchResultThreadFunc(search::Result const & result, int queryId)
{
emit SearchResultSignal(new search::Result(result));
if (queryId == m_queryId)
emit SearchResultSignal(new search::Result(result), queryId);
}
void SearchPanel::OnSearchResult(search::Result * result)
void SearchPanel::OnSearchResult(search::Result * result, int queryId)
{
if (queryId != m_queryId)
return;
if (!result->GetString().empty()) // last element
{
int const rowCount = m_pTable->rowCount();
@ -77,11 +81,12 @@ void SearchPanel::OnSearchTextChanged(QString const & str)
m_pTable->clear();
m_pTable->setRowCount(0);
ClearVector(m_results);
++m_queryId;
QString const normalized = str.normalized(QString::NormalizationForm_KC);
if (!normalized.isEmpty())
m_pDrawWidget->Search(normalized.toUtf8().constData(),
bind(&SearchPanel::SearchResultThreadFunc, this, _1));
bind(&SearchPanel::SearchResultThreadFunc, this, _1, m_queryId));
}
void SearchPanel::OnSearchPanelItemClicked(int row, int)

View file

@ -22,14 +22,15 @@ class SearchPanel : public QWidget
/// Stores current search results
vector<search::Result *> m_results;
int volatile m_queryId;
Q_OBJECT
signals:
void SearchResultSignal(search::Result * result);
void SearchResultSignal(search::Result * result, int queryId);
private:
void SearchResultThreadFunc(search::Result const & result);
void SearchResultThreadFunc(search::Result const & result, int queryId);
public:
explicit SearchPanel(DrawWidget * drawWidget, QWidget * parent);
@ -39,7 +40,7 @@ protected slots:
void OnSearchPanelItemClicked(int row, int column);
void OnSearchTextChanged(QString const &);
/// Called via signal to support multithreading
void OnSearchResult(search::Result * result);
void OnSearchResult(search::Result * result, int queryId);
};
}

View file

@ -1,14 +1,17 @@
#include "engine.hpp"
#include "query.hpp"
#include "result.hpp"
#include "../platform/concurrent_runner.hpp"
#include "../indexer/feature.hpp"
#include "../std/function.hpp"
#include "../std/string.hpp"
#include "../std/vector.hpp"
namespace search
{
Engine::Engine(IndexType const * pIndex) : m_pIndex(pIndex)
Engine::Engine(IndexType const * pIndex)
: m_pIndex(pIndex), m_pRunner(new threads::ConcurrentRunner)
{
}
@ -16,8 +19,8 @@ void Engine::Search(string const & queryText,
m2::RectD const & rect,
function<void (Result const &)> const & f)
{
impl::Query query(queryText, rect, m_pIndex);
query.Search(f);
impl::Query * pQuery = new impl::Query(queryText, rect, m_pIndex);
m_pRunner->Run(bind(&impl::Query::SearchAndDestroy, pQuery, f));
}
} // namespace search

View file

@ -2,7 +2,9 @@
#include "../indexer/index.hpp"
#include "../geometry/rect2d.hpp"
#include "../base/base.hpp"
#include "../base/runner.hpp"
#include "../std/function.hpp"
#include "../std/scoped_ptr.hpp"
#include "../std/string.hpp"
class FileReader;
@ -26,6 +28,7 @@ public:
private:
IndexType const * m_pIndex;
scoped_ptr<threads::IRunner> m_pRunner;
};
} // namespace search

View file

@ -90,7 +90,7 @@ struct FeatureProcessor
} // unnamed namespace
Query::Query(string const & query, m2::RectD const & viewport, IndexType const * pIndex)
: m_queryText(query), m_viewport(viewport), m_pIndex(pIndex)
: m_queryText(query), m_viewport(viewport), m_pIndex(pIndex), m_bTerminate(false)
{
search::Delimiters delims;
SplitAndNormalizeAndSimplifyString(query, MakeBackInsertFunctor(m_keywords), delims);
@ -152,6 +152,12 @@ void Query::Search(function<void (Result const &)> const & f)
f(*it);
}
void Query::SearchAndDestroy(function<void (const Result &)> const & f)
{
Search(f);
delete this;
}
void Query::AddResult(IntermediateResult const & result)
{
if (m_results.size() < 10)

View file

@ -26,9 +26,15 @@ public:
// Search with parameters, passed in constructor.
void Search(function<void (Result const &)> const & f);
// Search and delete this.
void SearchAndDestroy(function<void (Result const &)> const & f);
// Add result for scoring.
void AddResult(IntermediateResult const & result);
// Set a flag that query is not active any more and should terminate.
void SetTerminateFlag() volatile { m_bTerminate = true; }
m2::RectD const & GetViewport() const { return m_viewport; }
vector<strings::UniString> const & GetKeywords() const { return m_keywords; }
strings::UniString const & GetPrefix() const { return m_prefix; }
@ -44,6 +50,8 @@ private:
IndexType::Query m_indexQuery;
priority_queue<IntermediateResult> m_results;
bool volatile m_bTerminate;
};
} // namespace search::impl