xref: /glogg/src/data/logdataworkerthread.h (revision bb02e0acf44ddb4e4f83d6127a1e488789162922)
1*bb02e0acSNicolas Bonnefon /*
2*bb02e0acSNicolas Bonnefon  * Copyright (C) 2009, 2010 Nicolas Bonnefon and other contributors
3*bb02e0acSNicolas Bonnefon  *
4*bb02e0acSNicolas Bonnefon  * This file is part of glogg.
5*bb02e0acSNicolas Bonnefon  *
6*bb02e0acSNicolas Bonnefon  * glogg is free software: you can redistribute it and/or modify
7*bb02e0acSNicolas Bonnefon  * it under the terms of the GNU General Public License as published by
8*bb02e0acSNicolas Bonnefon  * the Free Software Foundation, either version 3 of the License, or
9*bb02e0acSNicolas Bonnefon  * (at your option) any later version.
10*bb02e0acSNicolas Bonnefon  *
11*bb02e0acSNicolas Bonnefon  * glogg is distributed in the hope that it will be useful,
12*bb02e0acSNicolas Bonnefon  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13*bb02e0acSNicolas Bonnefon  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14*bb02e0acSNicolas Bonnefon  * GNU General Public License for more details.
15*bb02e0acSNicolas Bonnefon  *
16*bb02e0acSNicolas Bonnefon  * You should have received a copy of the GNU General Public License
17*bb02e0acSNicolas Bonnefon  * along with glogg.  If not, see <http://www.gnu.org/licenses/>.
18*bb02e0acSNicolas Bonnefon  */
19*bb02e0acSNicolas Bonnefon 
20*bb02e0acSNicolas Bonnefon #ifndef LOGDATAWORKERTHREAD_H
21*bb02e0acSNicolas Bonnefon #define LOGDATAWORKERTHREAD_H
22*bb02e0acSNicolas Bonnefon 
23*bb02e0acSNicolas Bonnefon #include <QObject>
24*bb02e0acSNicolas Bonnefon #include <QThread>
25*bb02e0acSNicolas Bonnefon #include <QMutex>
26*bb02e0acSNicolas Bonnefon #include <QWaitCondition>
27*bb02e0acSNicolas Bonnefon #include <QVector>
28*bb02e0acSNicolas Bonnefon 
29*bb02e0acSNicolas Bonnefon // This class is a list of end of lines position,
30*bb02e0acSNicolas Bonnefon // in addition to a list of qint64 (positions within the files)
31*bb02e0acSNicolas Bonnefon // it can keep track of whether the final LF was added (for non-LF terminated
32*bb02e0acSNicolas Bonnefon // files) and remove it when more data are added.
33*bb02e0acSNicolas Bonnefon class LinePositionArray
34*bb02e0acSNicolas Bonnefon {
35*bb02e0acSNicolas Bonnefon   public:
36*bb02e0acSNicolas Bonnefon     // Default constructor
37*bb02e0acSNicolas Bonnefon     LinePositionArray() : array()
38*bb02e0acSNicolas Bonnefon     { fakeFinalLF_ = false; }
39*bb02e0acSNicolas Bonnefon     // Copy constructor
40*bb02e0acSNicolas Bonnefon     inline LinePositionArray( const LinePositionArray& orig )
41*bb02e0acSNicolas Bonnefon         : array(orig.array)
42*bb02e0acSNicolas Bonnefon     { fakeFinalLF_ = orig.fakeFinalLF_; }
43*bb02e0acSNicolas Bonnefon 
44*bb02e0acSNicolas Bonnefon     // Add a new line position at the given position
45*bb02e0acSNicolas Bonnefon     inline void append( qint64 pos )
46*bb02e0acSNicolas Bonnefon     { array.append( pos ); }
47*bb02e0acSNicolas Bonnefon     // Size of the array
48*bb02e0acSNicolas Bonnefon     inline int size()
49*bb02e0acSNicolas Bonnefon     { return array.size(); }
50*bb02e0acSNicolas Bonnefon     // Extract an element
51*bb02e0acSNicolas Bonnefon     inline qint64 at( int i ) const
52*bb02e0acSNicolas Bonnefon     { return array.at( i ); }
53*bb02e0acSNicolas Bonnefon     inline qint64 operator[]( int i ) const
54*bb02e0acSNicolas Bonnefon     { return array.at( i ); }
55*bb02e0acSNicolas Bonnefon     // Set the presence of a fake final LF
56*bb02e0acSNicolas Bonnefon     // Must be used after 'append'-ing a fake LF at the end.
57*bb02e0acSNicolas Bonnefon     void setFakeFinalLF( bool finalLF=true )
58*bb02e0acSNicolas Bonnefon     { fakeFinalLF_ = finalLF; }
59*bb02e0acSNicolas Bonnefon 
60*bb02e0acSNicolas Bonnefon     // Add another list to this one, removing any fake LF on this list.
61*bb02e0acSNicolas Bonnefon     LinePositionArray& operator+= ( const LinePositionArray& other )
62*bb02e0acSNicolas Bonnefon     {
63*bb02e0acSNicolas Bonnefon         // If our final LF is fake, we remove it
64*bb02e0acSNicolas Bonnefon         if ( fakeFinalLF_ )
65*bb02e0acSNicolas Bonnefon             this->array.pop_back();
66*bb02e0acSNicolas Bonnefon 
67*bb02e0acSNicolas Bonnefon         // Append the arrays
68*bb02e0acSNicolas Bonnefon         this->array += other.array;
69*bb02e0acSNicolas Bonnefon 
70*bb02e0acSNicolas Bonnefon         // In case the 'other' object has a fake LF
71*bb02e0acSNicolas Bonnefon         this->fakeFinalLF_ = other.fakeFinalLF_;
72*bb02e0acSNicolas Bonnefon 
73*bb02e0acSNicolas Bonnefon         return *this;
74*bb02e0acSNicolas Bonnefon     }
75*bb02e0acSNicolas Bonnefon 
76*bb02e0acSNicolas Bonnefon   private:
77*bb02e0acSNicolas Bonnefon     QVector<qint64> array;
78*bb02e0acSNicolas Bonnefon     bool fakeFinalLF_;
79*bb02e0acSNicolas Bonnefon };
80*bb02e0acSNicolas Bonnefon 
81*bb02e0acSNicolas Bonnefon // This class is a mutex protected set of indexing data.
82*bb02e0acSNicolas Bonnefon // It is thread safe.
83*bb02e0acSNicolas Bonnefon class IndexingData
84*bb02e0acSNicolas Bonnefon {
85*bb02e0acSNicolas Bonnefon   public:
86*bb02e0acSNicolas Bonnefon     IndexingData() : dataMutex_(), linePosition_(), maxLength_(0), indexedSize_(0) { }
87*bb02e0acSNicolas Bonnefon 
88*bb02e0acSNicolas Bonnefon     // Atomically get all the indexing data
89*bb02e0acSNicolas Bonnefon     void getAll( qint64* size, int* length,
90*bb02e0acSNicolas Bonnefon             LinePositionArray* linePosition );
91*bb02e0acSNicolas Bonnefon 
92*bb02e0acSNicolas Bonnefon     // Atomically set all the indexing data
93*bb02e0acSNicolas Bonnefon     // (overwriting the existing)
94*bb02e0acSNicolas Bonnefon     void setAll( qint64 size, int length,
95*bb02e0acSNicolas Bonnefon             const LinePositionArray& linePosition );
96*bb02e0acSNicolas Bonnefon 
97*bb02e0acSNicolas Bonnefon     // Atomically add to all the existing
98*bb02e0acSNicolas Bonnefon     // indexing data.
99*bb02e0acSNicolas Bonnefon     void addAll( qint64 size, int length,
100*bb02e0acSNicolas Bonnefon             const LinePositionArray& linePosition );
101*bb02e0acSNicolas Bonnefon 
102*bb02e0acSNicolas Bonnefon   private:
103*bb02e0acSNicolas Bonnefon     QMutex dataMutex_;
104*bb02e0acSNicolas Bonnefon 
105*bb02e0acSNicolas Bonnefon     LinePositionArray linePosition_;
106*bb02e0acSNicolas Bonnefon     int maxLength_;
107*bb02e0acSNicolas Bonnefon     qint64 indexedSize_;
108*bb02e0acSNicolas Bonnefon };
109*bb02e0acSNicolas Bonnefon 
110*bb02e0acSNicolas Bonnefon class IndexOperation : public QObject
111*bb02e0acSNicolas Bonnefon {
112*bb02e0acSNicolas Bonnefon   Q_OBJECT
113*bb02e0acSNicolas Bonnefon   public:
114*bb02e0acSNicolas Bonnefon     IndexOperation( QString& fileName, bool* interruptRequest );
115*bb02e0acSNicolas Bonnefon 
116*bb02e0acSNicolas Bonnefon     virtual ~IndexOperation() { }
117*bb02e0acSNicolas Bonnefon 
118*bb02e0acSNicolas Bonnefon     // Start the indexing operation, returns true if it has been done
119*bb02e0acSNicolas Bonnefon     // and false if it has been cancelled (results not copied)
120*bb02e0acSNicolas Bonnefon     virtual bool start( IndexingData& result ) = 0;
121*bb02e0acSNicolas Bonnefon 
122*bb02e0acSNicolas Bonnefon   signals:
123*bb02e0acSNicolas Bonnefon     void indexingProgressed( int );
124*bb02e0acSNicolas Bonnefon 
125*bb02e0acSNicolas Bonnefon   protected:
126*bb02e0acSNicolas Bonnefon     static const int sizeChunk;
127*bb02e0acSNicolas Bonnefon 
128*bb02e0acSNicolas Bonnefon     // Returns the total size indexed
129*bb02e0acSNicolas Bonnefon     qint64 doIndex( LinePositionArray& linePosition, int* maxLength,
130*bb02e0acSNicolas Bonnefon             qint64 initialPosition );
131*bb02e0acSNicolas Bonnefon 
132*bb02e0acSNicolas Bonnefon     QString fileName_;
133*bb02e0acSNicolas Bonnefon     bool* interruptRequest_;
134*bb02e0acSNicolas Bonnefon };
135*bb02e0acSNicolas Bonnefon 
136*bb02e0acSNicolas Bonnefon class FullIndexOperation : public IndexOperation
137*bb02e0acSNicolas Bonnefon {
138*bb02e0acSNicolas Bonnefon   public:
139*bb02e0acSNicolas Bonnefon     FullIndexOperation( QString& fileName, bool* interruptRequest )
140*bb02e0acSNicolas Bonnefon         : IndexOperation( fileName, interruptRequest ) { }
141*bb02e0acSNicolas Bonnefon     virtual bool start( IndexingData& result );
142*bb02e0acSNicolas Bonnefon };
143*bb02e0acSNicolas Bonnefon 
144*bb02e0acSNicolas Bonnefon class PartialIndexOperation : public IndexOperation
145*bb02e0acSNicolas Bonnefon {
146*bb02e0acSNicolas Bonnefon   public:
147*bb02e0acSNicolas Bonnefon     PartialIndexOperation( QString& fileName, bool* interruptRequest, qint64 position );
148*bb02e0acSNicolas Bonnefon     virtual bool start( IndexingData& result );
149*bb02e0acSNicolas Bonnefon 
150*bb02e0acSNicolas Bonnefon   private:
151*bb02e0acSNicolas Bonnefon     qint64 initialPosition_;
152*bb02e0acSNicolas Bonnefon };
153*bb02e0acSNicolas Bonnefon 
154*bb02e0acSNicolas Bonnefon // Create and manage the thread doing loading/indexing for
155*bb02e0acSNicolas Bonnefon // the creating LogData. One LogDataWorkerThread is used
156*bb02e0acSNicolas Bonnefon // per LogData instance.
157*bb02e0acSNicolas Bonnefon // Note everything except the run() function is in the LogData's
158*bb02e0acSNicolas Bonnefon // thread.
159*bb02e0acSNicolas Bonnefon class LogDataWorkerThread : public QThread
160*bb02e0acSNicolas Bonnefon {
161*bb02e0acSNicolas Bonnefon   Q_OBJECT
162*bb02e0acSNicolas Bonnefon 
163*bb02e0acSNicolas Bonnefon   public:
164*bb02e0acSNicolas Bonnefon     LogDataWorkerThread();
165*bb02e0acSNicolas Bonnefon     ~LogDataWorkerThread();
166*bb02e0acSNicolas Bonnefon 
167*bb02e0acSNicolas Bonnefon     // Attaches to a file on disk. Attaching to a non existant file
168*bb02e0acSNicolas Bonnefon     // will work, it will just appear as an empty file.
169*bb02e0acSNicolas Bonnefon     void attachFile( const QString& fileName );
170*bb02e0acSNicolas Bonnefon     // Instructs the thread to start a new full indexing of the file, sending
171*bb02e0acSNicolas Bonnefon     // signals as it progresses.
172*bb02e0acSNicolas Bonnefon     void indexAll();
173*bb02e0acSNicolas Bonnefon     // Instructs the thread to start a partial indexing (starting at
174*bb02e0acSNicolas Bonnefon     // the index passed).
175*bb02e0acSNicolas Bonnefon     void indexAdditionalLines( qint64 position );
176*bb02e0acSNicolas Bonnefon     // Interrupts the indexing if one is in progress
177*bb02e0acSNicolas Bonnefon     void interrupt();
178*bb02e0acSNicolas Bonnefon 
179*bb02e0acSNicolas Bonnefon     // Returns a copy of the current indexing data
180*bb02e0acSNicolas Bonnefon     void getIndexingData( qint64* indexedSize,
181*bb02e0acSNicolas Bonnefon             int* maxLength, LinePositionArray* linePosition );
182*bb02e0acSNicolas Bonnefon 
183*bb02e0acSNicolas Bonnefon   signals:
184*bb02e0acSNicolas Bonnefon     // Sent during the indexing process to signal progress
185*bb02e0acSNicolas Bonnefon     // percent being the percentage of completion.
186*bb02e0acSNicolas Bonnefon     void indexingProgressed( int percent );
187*bb02e0acSNicolas Bonnefon     // Sent when indexing is finished, signals the client
188*bb02e0acSNicolas Bonnefon     // to copy the new data back.
189*bb02e0acSNicolas Bonnefon     void indexingFinished( bool success );
190*bb02e0acSNicolas Bonnefon 
191*bb02e0acSNicolas Bonnefon   protected:
192*bb02e0acSNicolas Bonnefon     void run();
193*bb02e0acSNicolas Bonnefon 
194*bb02e0acSNicolas Bonnefon   private:
195*bb02e0acSNicolas Bonnefon     void doIndexAll();
196*bb02e0acSNicolas Bonnefon 
197*bb02e0acSNicolas Bonnefon     // Mutex to protect operationRequested_ and friends
198*bb02e0acSNicolas Bonnefon     QMutex mutex_;
199*bb02e0acSNicolas Bonnefon     QWaitCondition operationRequestedCond_;
200*bb02e0acSNicolas Bonnefon     QWaitCondition nothingToDoCond_;
201*bb02e0acSNicolas Bonnefon     QString fileName_;
202*bb02e0acSNicolas Bonnefon 
203*bb02e0acSNicolas Bonnefon     // Set when the thread must die
204*bb02e0acSNicolas Bonnefon     bool terminate_;
205*bb02e0acSNicolas Bonnefon     bool interruptRequested_;
206*bb02e0acSNicolas Bonnefon     IndexOperation* operationRequested_;
207*bb02e0acSNicolas Bonnefon 
208*bb02e0acSNicolas Bonnefon     // Shared indexing data
209*bb02e0acSNicolas Bonnefon     IndexingData indexingData_;
210*bb02e0acSNicolas Bonnefon };
211*bb02e0acSNicolas Bonnefon 
212*bb02e0acSNicolas Bonnefon #endif
213