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