1bb02e0acSNicolas Bonnefon /* 2bb02e0acSNicolas Bonnefon * Copyright (C) 2009, 2010 Nicolas Bonnefon and other contributors 3bb02e0acSNicolas Bonnefon * 4bb02e0acSNicolas Bonnefon * This file is part of glogg. 5bb02e0acSNicolas Bonnefon * 6bb02e0acSNicolas Bonnefon * glogg is free software: you can redistribute it and/or modify 7bb02e0acSNicolas Bonnefon * it under the terms of the GNU General Public License as published by 8bb02e0acSNicolas Bonnefon * the Free Software Foundation, either version 3 of the License, or 9bb02e0acSNicolas Bonnefon * (at your option) any later version. 10bb02e0acSNicolas Bonnefon * 11bb02e0acSNicolas Bonnefon * glogg is distributed in the hope that it will be useful, 12bb02e0acSNicolas Bonnefon * but WITHOUT ANY WARRANTY; without even the implied warranty of 13bb02e0acSNicolas Bonnefon * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14bb02e0acSNicolas Bonnefon * GNU General Public License for more details. 15bb02e0acSNicolas Bonnefon * 16bb02e0acSNicolas Bonnefon * You should have received a copy of the GNU General Public License 17bb02e0acSNicolas Bonnefon * along with glogg. If not, see <http://www.gnu.org/licenses/>. 18bb02e0acSNicolas Bonnefon */ 19bb02e0acSNicolas Bonnefon 20bb02e0acSNicolas Bonnefon #ifndef LOGFILTEREDDATAWORKERTHREAD_H 21bb02e0acSNicolas Bonnefon #define LOGFILTEREDDATAWORKERTHREAD_H 22bb02e0acSNicolas Bonnefon 23bb02e0acSNicolas Bonnefon #include <QObject> 24bb02e0acSNicolas Bonnefon #include <QThread> 25bb02e0acSNicolas Bonnefon #include <QMutex> 26bb02e0acSNicolas Bonnefon #include <QWaitCondition> 274fb0346eSAnton Filimonov #include <QRegularExpression> 28bb02e0acSNicolas Bonnefon #include <QList> 29bb02e0acSNicolas Bonnefon 30bb02e0acSNicolas Bonnefon class LogData; 31bb02e0acSNicolas Bonnefon 32ced968a9SNicolas Bonnefon // Line number are unsigned 32 bits for now. 33ced968a9SNicolas Bonnefon typedef uint32_t LineNumber; 34ced968a9SNicolas Bonnefon 35bb02e0acSNicolas Bonnefon // Class encapsulating a single matching line 36bb02e0acSNicolas Bonnefon // Contains the line number the line was found in and its content. 37bb02e0acSNicolas Bonnefon class MatchingLine { 38bb02e0acSNicolas Bonnefon public: MatchingLine(LineNumber line)39ced968a9SNicolas Bonnefon MatchingLine( LineNumber line ) { lineNumber_ = line; }; 40bb02e0acSNicolas Bonnefon 41bb02e0acSNicolas Bonnefon // Accessors lineNumber()42ced968a9SNicolas Bonnefon LineNumber lineNumber() const { return lineNumber_; } 43bb02e0acSNicolas Bonnefon 443ff6c941SAnton Filimonov bool operator <( const MatchingLine& other) const 453ff6c941SAnton Filimonov { return lineNumber_ < other.lineNumber_; } 463ff6c941SAnton Filimonov 47bb02e0acSNicolas Bonnefon private: 48ced968a9SNicolas Bonnefon LineNumber lineNumber_; 49bb02e0acSNicolas Bonnefon }; 50bb02e0acSNicolas Bonnefon 51ced968a9SNicolas Bonnefon // This is an array of matching lines. 52ced968a9SNicolas Bonnefon // It shall be implemented for random lookup speed, so 53ced968a9SNicolas Bonnefon // a fixed "in-place" array (vector) is probably fine. 54ced968a9SNicolas Bonnefon typedef std::vector<MatchingLine> SearchResultArray; 55bb02e0acSNicolas Bonnefon 56bb02e0acSNicolas Bonnefon // This class is a mutex protected set of search result data. 57bb02e0acSNicolas Bonnefon // It is thread safe. 58bb02e0acSNicolas Bonnefon class SearchData 59bb02e0acSNicolas Bonnefon { 60bb02e0acSNicolas Bonnefon public: SearchData()61bb02e0acSNicolas Bonnefon SearchData() : dataMutex_(), matches_(), maxLength_(0) { } 62bb02e0acSNicolas Bonnefon 63bb02e0acSNicolas Bonnefon // Atomically get all the search data 64bb02e0acSNicolas Bonnefon void getAll( int* length, SearchResultArray* matches, 65bb02e0acSNicolas Bonnefon qint64* nbLinesProcessed ) const; 66bb02e0acSNicolas Bonnefon // Atomically set all the search data 67bb02e0acSNicolas Bonnefon // (overwriting the existing) 68ced968a9SNicolas Bonnefon // (the matches are always moved) 69ced968a9SNicolas Bonnefon void setAll( int length, SearchResultArray&& matches ); 70bb02e0acSNicolas Bonnefon // Atomically add to all the existing search data. 71ced968a9SNicolas Bonnefon void addAll( int length, const SearchResultArray& matches, LineNumber nbLinesProcessed ); 72bb02e0acSNicolas Bonnefon // Get the number of matches 73ced968a9SNicolas Bonnefon LineNumber getNbMatches() const; 74bb02e0acSNicolas Bonnefon // Delete the match for the passed line (if it exist) 75ced968a9SNicolas Bonnefon void deleteMatch( LineNumber line ); 76bb02e0acSNicolas Bonnefon // Atomically clear the data. 77bb02e0acSNicolas Bonnefon void clear(); 78bb02e0acSNicolas Bonnefon 79bb02e0acSNicolas Bonnefon private: 80bb02e0acSNicolas Bonnefon mutable QMutex dataMutex_; 81bb02e0acSNicolas Bonnefon 82bb02e0acSNicolas Bonnefon SearchResultArray matches_; 83bb02e0acSNicolas Bonnefon int maxLength_; 84ced968a9SNicolas Bonnefon LineNumber nbLinesProcessed_; 85bb02e0acSNicolas Bonnefon }; 86bb02e0acSNicolas Bonnefon 87bb02e0acSNicolas Bonnefon class SearchOperation : public QObject 88bb02e0acSNicolas Bonnefon { 89bb02e0acSNicolas Bonnefon Q_OBJECT 90bb02e0acSNicolas Bonnefon public: 91bb02e0acSNicolas Bonnefon SearchOperation(const LogData* sourceLogData, 924fb0346eSAnton Filimonov const QRegularExpression ®Exp, bool* interruptRequest ); 93bb02e0acSNicolas Bonnefon ~SearchOperation()94bb02e0acSNicolas Bonnefon virtual ~SearchOperation() { } 95bb02e0acSNicolas Bonnefon 96bb02e0acSNicolas Bonnefon // Start the search operation, returns true if it has been done 97bb02e0acSNicolas Bonnefon // and false if it has been cancelled (results not copied) 98bb02e0acSNicolas Bonnefon virtual void start( SearchData& result ) = 0; 99bb02e0acSNicolas Bonnefon 100bb02e0acSNicolas Bonnefon signals: 101*c59cadb3SNicolas Bonnefon void searchProgressed( int percent, int nbMatches, qint64 started ); 102bb02e0acSNicolas Bonnefon 103bb02e0acSNicolas Bonnefon protected: 104bb02e0acSNicolas Bonnefon static const int nbLinesInChunk; 105bb02e0acSNicolas Bonnefon 106bb02e0acSNicolas Bonnefon // Implement the common part of the search, passing 107bb02e0acSNicolas Bonnefon // the shared results and the line to begin the search from. 108bb02e0acSNicolas Bonnefon void doSearch( SearchData& result, qint64 initialLine ); 109bb02e0acSNicolas Bonnefon 110bb02e0acSNicolas Bonnefon bool* interruptRequested_; 1114fb0346eSAnton Filimonov const QRegularExpression regexp_; 112bb02e0acSNicolas Bonnefon const LogData* sourceLogData_; 113bb02e0acSNicolas Bonnefon }; 114bb02e0acSNicolas Bonnefon 115bb02e0acSNicolas Bonnefon class FullSearchOperation : public SearchOperation 116bb02e0acSNicolas Bonnefon { 117bb02e0acSNicolas Bonnefon public: FullSearchOperation(const LogData * sourceLogData,const QRegularExpression & regExp,bool * interruptRequest)1184fb0346eSAnton Filimonov FullSearchOperation( const LogData* sourceLogData, const QRegularExpression& regExp, 119bb02e0acSNicolas Bonnefon bool* interruptRequest ) 120bb02e0acSNicolas Bonnefon : SearchOperation( sourceLogData, regExp, interruptRequest ) {} 121bb02e0acSNicolas Bonnefon virtual void start( SearchData& result ); 122bb02e0acSNicolas Bonnefon }; 123bb02e0acSNicolas Bonnefon 124bb02e0acSNicolas Bonnefon class UpdateSearchOperation : public SearchOperation 125bb02e0acSNicolas Bonnefon { 126bb02e0acSNicolas Bonnefon public: UpdateSearchOperation(const LogData * sourceLogData,const QRegularExpression & regExp,bool * interruptRequest,qint64 position)1274fb0346eSAnton Filimonov UpdateSearchOperation( const LogData* sourceLogData, const QRegularExpression& regExp, 128bb02e0acSNicolas Bonnefon bool* interruptRequest, qint64 position ) 129bb02e0acSNicolas Bonnefon : SearchOperation( sourceLogData, regExp, interruptRequest ), 130bb02e0acSNicolas Bonnefon initialPosition_( position ) {} 131bb02e0acSNicolas Bonnefon virtual void start( SearchData& result ); 132bb02e0acSNicolas Bonnefon 133bb02e0acSNicolas Bonnefon private: 134bb02e0acSNicolas Bonnefon qint64 initialPosition_; 135bb02e0acSNicolas Bonnefon }; 136bb02e0acSNicolas Bonnefon 137bb02e0acSNicolas Bonnefon // Create and manage the thread doing loading/indexing for 138bb02e0acSNicolas Bonnefon // the creating LogData. One LogDataWorkerThread is used 139bb02e0acSNicolas Bonnefon // per LogData instance. 140bb02e0acSNicolas Bonnefon // Note everything except the run() function is in the LogData's 141bb02e0acSNicolas Bonnefon // thread. 142bb02e0acSNicolas Bonnefon class LogFilteredDataWorkerThread : public QThread 143bb02e0acSNicolas Bonnefon { 144bb02e0acSNicolas Bonnefon Q_OBJECT 145bb02e0acSNicolas Bonnefon 146bb02e0acSNicolas Bonnefon public: 147bb02e0acSNicolas Bonnefon LogFilteredDataWorkerThread( const LogData* sourceLogData ); 148bb02e0acSNicolas Bonnefon ~LogFilteredDataWorkerThread(); 149bb02e0acSNicolas Bonnefon 150bb02e0acSNicolas Bonnefon // Start the search with the passed regexp 1514fb0346eSAnton Filimonov void search(const QRegularExpression ®Exp ); 152bb02e0acSNicolas Bonnefon // Continue the previous search starting at the passed position 153bb02e0acSNicolas Bonnefon // in the source file (line number) 1544fb0346eSAnton Filimonov void updateSearch( const QRegularExpression& regExp, qint64 position ); 155bb02e0acSNicolas Bonnefon // Interrupts the search if one is in progress 156bb02e0acSNicolas Bonnefon void interrupt(); 157bb02e0acSNicolas Bonnefon 158bb02e0acSNicolas Bonnefon // Returns a copy of the current indexing data 159bb02e0acSNicolas Bonnefon void getSearchResult( int* maxLength, SearchResultArray* searchMatches, 160bb02e0acSNicolas Bonnefon qint64* nbLinesProcessed ); 161bb02e0acSNicolas Bonnefon 162bb02e0acSNicolas Bonnefon signals: 163bb02e0acSNicolas Bonnefon // Sent during the indexing process to signal progress 164bb02e0acSNicolas Bonnefon // percent being the percentage of completion. 165*c59cadb3SNicolas Bonnefon void searchProgressed( int percent, int nbMatches, qint64 initial_position ); 166bb02e0acSNicolas Bonnefon // Sent when indexing is finished, signals the client 167bb02e0acSNicolas Bonnefon // to copy the new data back. 168bb02e0acSNicolas Bonnefon void searchFinished(); 169bb02e0acSNicolas Bonnefon 170bb02e0acSNicolas Bonnefon protected: 171bb02e0acSNicolas Bonnefon void run(); 172bb02e0acSNicolas Bonnefon 173bb02e0acSNicolas Bonnefon private: 174bb02e0acSNicolas Bonnefon const LogData* sourceLogData_; 175bb02e0acSNicolas Bonnefon 176bb02e0acSNicolas Bonnefon // Mutex to protect operationRequested_ and friends 177bb02e0acSNicolas Bonnefon QMutex mutex_; 178bb02e0acSNicolas Bonnefon QWaitCondition operationRequestedCond_; 179bb02e0acSNicolas Bonnefon QWaitCondition nothingToDoCond_; 180bb02e0acSNicolas Bonnefon 181bb02e0acSNicolas Bonnefon // Set when the thread must die 182bb02e0acSNicolas Bonnefon bool terminate_; 183bb02e0acSNicolas Bonnefon bool interruptRequested_; 184bb02e0acSNicolas Bonnefon SearchOperation* operationRequested_; 185bb02e0acSNicolas Bonnefon 186bb02e0acSNicolas Bonnefon // Shared indexing data 187bb02e0acSNicolas Bonnefon SearchData searchData_; 188bb02e0acSNicolas Bonnefon }; 189bb02e0acSNicolas Bonnefon 190bb02e0acSNicolas Bonnefon #endif 191