xref: /glogg/src/data/logfiltereddataworkerthread.h (revision c633ced33b4f2c2cf77c0c80a15fa73a7f13ad9f)
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 <QRegExp>
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   private:
45     LineNumber lineNumber_;
46 };
47 
48 // This is an array of matching lines.
49 // It shall be implemented for random lookup speed, so
50 // a fixed "in-place" array (vector) is probably fine.
51 typedef std::vector<MatchingLine> SearchResultArray;
52 
53 // This class is a mutex protected set of search result data.
54 // It is thread safe.
55 class SearchData
56 {
57   public:
58     SearchData() : dataMutex_(), matches_(), maxLength_(0) { }
59 
60     // Atomically get all the search data
61     void getAll( int* length, SearchResultArray* matches,
62             qint64* nbLinesProcessed ) const;
63     // Atomically set all the search data
64     // (overwriting the existing)
65     // (the matches are always moved)
66     void setAll( int length, SearchResultArray&& matches );
67     // Atomically add to all the existing search data.
68     void addAll( int length, const SearchResultArray& matches, LineNumber nbLinesProcessed );
69     // Get the number of matches
70     LineNumber getNbMatches() const;
71     // Delete the match for the passed line (if it exist)
72     void deleteMatch( LineNumber line );
73     // Atomically clear the data.
74     void clear();
75 
76   private:
77     mutable QMutex dataMutex_;
78 
79     SearchResultArray matches_;
80     int maxLength_;
81     LineNumber nbLinesProcessed_;
82 };
83 
84 class SearchOperation : public QObject
85 {
86   Q_OBJECT
87   public:
88     SearchOperation( const LogData* sourceLogData,
89             const QRegExp& regExp, bool* interruptRequest );
90 
91     virtual ~SearchOperation() { }
92 
93     // Start the search operation, returns true if it has been done
94     // and false if it has been cancelled (results not copied)
95     virtual void start( SearchData& result ) = 0;
96 
97   signals:
98     void searchProgressed( int percent, int nbMatches );
99 
100   protected:
101     static const int nbLinesInChunk;
102 
103     // Implement the common part of the search, passing
104     // the shared results and the line to begin the search from.
105     void doSearch( SearchData& result, qint64 initialLine );
106 
107     bool* interruptRequested_;
108     const QRegExp regexp_;
109     const LogData* sourceLogData_;
110 };
111 
112 class FullSearchOperation : public SearchOperation
113 {
114   public:
115     FullSearchOperation( const LogData* sourceLogData, const QRegExp& regExp,
116             bool* interruptRequest )
117         : SearchOperation( sourceLogData, regExp, interruptRequest ) {}
118     virtual void start( SearchData& result );
119 };
120 
121 class UpdateSearchOperation : public SearchOperation
122 {
123   public:
124     UpdateSearchOperation( const LogData* sourceLogData, const QRegExp& regExp,
125             bool* interruptRequest, qint64 position )
126         : SearchOperation( sourceLogData, regExp, interruptRequest ),
127         initialPosition_( position ) {}
128     virtual void start( SearchData& result );
129 
130   private:
131     qint64 initialPosition_;
132 };
133 
134 // Create and manage the thread doing loading/indexing for
135 // the creating LogData. One LogDataWorkerThread is used
136 // per LogData instance.
137 // Note everything except the run() function is in the LogData's
138 // thread.
139 class LogFilteredDataWorkerThread : public QThread
140 {
141   Q_OBJECT
142 
143   public:
144     LogFilteredDataWorkerThread( const LogData* sourceLogData );
145     ~LogFilteredDataWorkerThread();
146 
147     // Start the search with the passed regexp
148     void search( const QRegExp& regExp );
149     // Continue the previous search starting at the passed position
150     // in the source file (line number)
151     void updateSearch( const QRegExp& regExp, qint64 position );
152     // Interrupts the search if one is in progress
153     void interrupt();
154 
155     // Returns a copy of the current indexing data
156     void getSearchResult( int* maxLength, SearchResultArray* searchMatches,
157            qint64* nbLinesProcessed );
158 
159   signals:
160     // Sent during the indexing process to signal progress
161     // percent being the percentage of completion.
162     void searchProgressed( int percent, int nbMatches );
163     // Sent when indexing is finished, signals the client
164     // to copy the new data back.
165     void searchFinished();
166 
167   protected:
168     void run();
169 
170   private:
171     const LogData* sourceLogData_;
172 
173     // Mutex to protect operationRequested_ and friends
174     QMutex mutex_;
175     QWaitCondition operationRequestedCond_;
176     QWaitCondition nothingToDoCond_;
177 
178     // Set when the thread must die
179     bool terminate_;
180     bool interruptRequested_;
181     SearchOperation* operationRequested_;
182 
183     // Shared indexing data
184     SearchData searchData_;
185 };
186 
187 #endif
188