diff --git a/src/lib/data/fulltextsearch/FullTextSearchIndex.cpp b/src/lib/data/fulltextsearch/FullTextSearchIndex.cpp index f8b36cd7..087db7bf 100644 --- a/src/lib/data/fulltextsearch/FullTextSearchIndex.cpp +++ b/src/lib/data/fulltextsearch/FullTextSearchIndex.cpp @@ -29,16 +29,21 @@ std::vector FullTextSearchIndex::searchForTerm(const std:: TRACE(); std::vector ret; - FullTextSearchResult hit; { std::lock_guard lock(m_filesMutex); for (auto& f : m_files) { + FullTextSearchResult hit; hit.fileId = f.fileId; hit.positions = f.array.searchForTerm(term); - ret.push_back(hit); + std::sort(hit.positions.begin(), hit.positions.end()); + if (!hit.positions.empty()) + { + ret.push_back(hit); + } } } + return ret; } diff --git a/src/lib/data/storage/PersistentStorage.cpp b/src/lib/data/storage/PersistentStorage.cpp index 877f7bf8..a0855d08 100644 --- a/src/lib/data/storage/PersistentStorage.cpp +++ b/src/lib/data/storage/PersistentStorage.cpp @@ -552,58 +552,75 @@ std::shared_ptr PersistentStorage::getFullTextSearchLo false, true ).dispatch(); - const int termLength = searchTerm.length(); - - for (const FullTextSearchResult& fileHits : m_fullTextSearchIndex.searchForTerm(searchTerm)) { - const FilePath filePath = getFileNodePath(fileHits.fileId); - std::shared_ptr fileContent = getFileContent(filePath, false); - - int charsTotal = 0; - int lineNumber = 1; - std::wstring line = codec.decode(fileContent->getLine(lineNumber)); - - for (int pos : fileHits.positions) + std::vector> threads; + std::mutex collectionMutex; + for (std::vector fileResults : utility::splitToEqualySizedParts(m_fullTextSearchIndex.searchForTerm(searchTerm), utility::getIdealThreadCount())) { - while (charsTotal + (int)line.length() <= pos) - { - charsTotal += line.length(); - lineNumber++; - line = codec.decode(fileContent->getLine(lineNumber)); - } + std::shared_ptr thread = std::make_shared( + [this, &searchTerm, &caseSensitive, &codec, /*no ref here!*/fileResults, &collection, &collectionMutex]() + { + const int termLength = searchTerm.length(); + for (const FullTextSearchResult& fileResult : fileResults) + { + const FilePath filePath = getFileNodePath(fileResult.fileId); + std::shared_ptr fileContent = getFileContent(filePath, false); - ParseLocation location; - location.startLineNumber = lineNumber; - location.startColumnNumber = pos - charsTotal + 1; + int charsTotal = 0; + int lineNumber = 1; + std::wstring line = codec.decode(fileContent->getLine(lineNumber)); - if (caseSensitive && line.substr(location.startColumnNumber - 1, termLength) != searchTerm) - { - continue; - } + for (int pos : fileResult.positions) + { + while (charsTotal + (int)line.length() <= pos) + { + charsTotal += line.length(); + lineNumber++; + line = codec.decode(fileContent->getLine(lineNumber)); + } - while ((charsTotal + (int)line.length()) < pos + termLength) - { - charsTotal += line.length(); - lineNumber++; - line = codec.decode(fileContent->getLine(lineNumber)); - } + ParseLocation location; + location.startLineNumber = lineNumber; + location.startColumnNumber = pos - charsTotal + 1; - location.endLineNumber = lineNumber; - location.endColumnNumber = pos + termLength - charsTotal; + if (caseSensitive && line.substr(location.startColumnNumber - 1, termLength) != searchTerm) + { + continue; + } + while ((charsTotal + (int)line.length()) < pos + termLength) + { + charsTotal += line.length(); + lineNumber++; + line = codec.decode(fileContent->getLine(lineNumber)); + } + location.endLineNumber = lineNumber; + location.endColumnNumber = pos + termLength - charsTotal; - // Set first bit to 1 to avoid collisions - const Id locationId = ~(~Id(0) >> 1) + collection->getSourceLocationCount() + 1; - - collection->addSourceLocation( - LOCATION_FULLTEXT_SEARCH, - locationId, - std::vector(), - filePath, - location.startLineNumber, - location.startColumnNumber, - location.endLineNumber, - location.endColumnNumber + { + std::lock_guard lock(collectionMutex); + // Set first bit to 1 to avoid collisions + const Id locationId = ~(~Id(0) >> 1) + collection->getSourceLocationCount() + 1; + collection->addSourceLocation( + LOCATION_FULLTEXT_SEARCH, + locationId, + std::vector(), + filePath, + location.startLineNumber, + location.startColumnNumber, + location.endLineNumber, + location.endColumnNumber + ); + } + } + } + } ); + threads.push_back(thread); + } + + for (std::shared_ptr thread : threads) + { + thread->join(); } } diff --git a/src/lib_utility/utility/TextCodec.cpp b/src/lib_utility/utility/TextCodec.cpp index 73c1354f..920710ad 100644 --- a/src/lib_utility/utility/TextCodec.cpp +++ b/src/lib_utility/utility/TextCodec.cpp @@ -5,6 +5,9 @@ TextCodec::TextCodec(const std::string& name) : m_name(name) { + m_codec = QTextCodec::codecForName(m_name.c_str()); + m_decoder = std::make_shared(m_codec); + m_encoder = std::make_shared(m_codec); } std::string TextCodec::getName() const @@ -14,8 +17,7 @@ std::string TextCodec::getName() const bool TextCodec::isValid() const { - QTextCodec* codec = QTextCodec::codecForName(m_name.c_str()); - if (codec) + if (m_codec) { return true; } @@ -24,23 +26,18 @@ bool TextCodec::isValid() const std::wstring TextCodec::decode(const std::string& unicodeString) const { - QTextCodec* codec = QTextCodec::codecForName(m_name.c_str()); - if (codec) + if (m_decoder) { - QTextDecoder decoder(codec); - return decoder.toUnicode(unicodeString.c_str()).toStdWString(); + return m_decoder->toUnicode(unicodeString.c_str()).toStdWString(); } return QString::fromStdString(unicodeString).toStdWString(); } std::string TextCodec::encode(const std::wstring& string) const { - QTextCodec* codec = QTextCodec::codecForName(m_name.c_str()); - if (codec) + if (m_encoder) { - QTextEncoder encoder(codec); - return encoder.fromUnicode(QString::fromStdWString(string)).toStdString(); + return m_encoder->fromUnicode(QString::fromStdWString(string)).toStdString(); } - return QString::fromStdWString(string).toStdString(); } diff --git a/src/lib_utility/utility/TextCodec.h b/src/lib_utility/utility/TextCodec.h index 19e3628a..2359bfa6 100644 --- a/src/lib_utility/utility/TextCodec.h +++ b/src/lib_utility/utility/TextCodec.h @@ -2,6 +2,11 @@ #define TEXT_CODEC_H #include +#include + +class QTextCodec; +class QTextDecoder; +class QTextEncoder; class TextCodec { @@ -17,6 +22,9 @@ public: private: const std::string m_name; + QTextCodec* m_codec; + std::shared_ptr m_decoder; + std::shared_ptr m_encoder; }; #endif // TEXT_CODEC_H