xref: /glogg/src/data/logfiltereddataworkerthread.h (revision c59cadb3bc56e902de41bd6b429f9d7bc056088a)
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 &regExp, 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 &regExp );
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