Skip to content

Commit

Permalink
Switch to single-thread matching on win32. Fix multithread matching o…
Browse files Browse the repository at this point in the history
…n nix
  • Loading branch information
variar committed Nov 16, 2017
1 parent 3a88764 commit 8aeb097
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 34 deletions.
4 changes: 2 additions & 2 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@ os: Visual Studio 2015
environment:
matrix:
- QT5: C:\Qt\5.9.1\mingw53_32
- QT5: C:\Qt\5.8\mingw53_32
- QT5: C:\Qt\5.7\mingw53_32
- QT5: C:\Qt\5.6\mingw49_32

matrix:
fast_finish: false
Expand All @@ -19,6 +17,8 @@ before_build:
- if %QT5:msvc=%==%QT5% g++ --version
- if %QT5:msvc=%==%QT5% set make=mingw32-make.exe
- if %QT5:msvc=%==%QT5% %make% --version
- if %QT5:msvc=%==%QT5% set MINGW=C:\Qt\Tools\mingw530_32

# VS2015
- if not %QT5:msvc=%==%QT5% call "%ProgramFiles(x86)%\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" amd64
- if not %QT5:msvc=%==%QT5% set make=nmake.exe
Expand Down
78 changes: 46 additions & 32 deletions src/data/logfiltereddataworkerthread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,25 @@ const int SearchOperation::nbLinesInChunk = 5000;

namespace
{
typedef std::pair<int, QString> NumberedLine;

void reduceMaxLength( int& max, int next )
struct PartialSearchResults
{
max = qMax(max, next);
}
PartialSearchResults() : maxLength{} {}

int getUntabifiedLength( const NumberedLine& line )
SearchResultArray matchingLines;
int maxLength;
};

PartialSearchResults filterLines(const QRegularExpression& regex, const QStringList& lines, qint64 chunkStart, size_t proc, size_t procs)
{
return AbstractLogData::getUntabifiedLength(line.second);
PartialSearchResults results;
for (qint64 i = proc; i < lines.size(); i += procs) {
const auto& l = lines.at(i);
if (regex.match(l).hasMatch()) {
results.maxLength = qMax(results.maxLength, AbstractLogData::getUntabifiedLength(l));
results.matchingLines.emplace_back(chunkStart + i);
}
}
return results;
}
}

Expand Down Expand Up @@ -243,11 +252,16 @@ void SearchOperation::doSearch( SearchData& searchData, qint64 initialLine )
int nbMatches = searchData.getNbMatches();
SearchResultArray currentList;

std::vector<NumberedLine> numberedLines;
#ifndef _WIN32
std::vector<QRegularExpression> regexp;

This comment has been minimized.

Copy link
@variar

variar Nov 16, 2017

Author Owner

This allows to avoid locking on shared regexp data on each match

for (int core = 0; core < QThread::idealThreadCount(); ++core) {
regexp.emplace_back(regexp_.pattern(), regexp_.patternOptions());
regexp.back().optimize();
}
#endif

// Ensure no re-alloc will be done
currentList.reserve( nbLinesInChunk );
numberedLines.reserve( nbLinesInChunk );

LOG(logDEBUG) << "Searching from line " << initialLine << " to " << nbSourceLines;

Expand All @@ -270,36 +284,36 @@ void SearchOperation::doSearch( SearchData& searchData, qint64 initialLine )
LOG(logDEBUG) << "Chunk starting at " << chunkStart <<
", " << lines.size() << " lines read.";

for ( int j = 0; j < lines.size(); ++j ) {
numberedLines.emplace_back( j, std::move( lines[j] ) );
}

QtConcurrent::blockingFilter( numberedLines,
[this]( const NumberedLine& line ) {
// implicitly shared, internal data access is thread-safe
auto localRegexp = regexp_;
return localRegexp.match( line.second ).hasMatch();
#ifndef _WIN32
if (regexp.size() > 0) {
std::vector<QFuture<PartialSearchResults>> partialResults;
for (auto i=0u; i<regexp.size(); ++i) {
partialResults.push_back(QtConcurrent::run(filterLines, regexp[i], lines, chunkStart, i, regexp.size()));
}
);

maxLength = qMax( maxLength,
QtConcurrent::blockingMappedReduced( numberedLines, getUntabifiedLength, reduceMaxLength ) );

std::transform( numberedLines.begin(), numberedLines.end(),
std::back_inserter( currentList ),
[&chunkStart]( const NumberedLine& matchedLine ) {
return MatchingLine( chunkStart + matchedLine.first );
}
);

nbMatches += numberedLines.size();
for (auto& f: partialResults) {
f.waitForFinished();
auto result = f.result();
currentList.insert(currentList.end(), result.matchingLines.begin(), result.matchingLines.end());
maxLength = qMax(maxLength, f.result().maxLength);
nbMatches += f.result().matchingLines.size();
}
std::sort(currentList.begin(), currentList.end());
}
else {
#endif
auto matchResults = filterLines(regexp_, lines, chunkStart, 0, 1);
currentList = std::move(matchResults.matchingLines);
maxLength = qMax(maxLength, matchResults.maxLength);
nbMatches += currentList.size();
#ifndef _WIN32
}
#endif

// After each block, copy the data to shared data
// and update the client
searchData.addAll( maxLength, currentList, chunkStart + linesInChunk );
currentList.clear();
numberedLines.clear();

}

emit searchProgressed( nbMatches, 100 );
Expand Down

0 comments on commit 8aeb097

Please sign in to comment.