xref: /glogg/src/data/logdataworkerthread.h (revision de1abac61b191ce1317b0ceaa43904b8f2fb2bd3)
1 /*
2  * Copyright (C) 2009, 2010, 2014, 2015 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 LOGDATAWORKERTHREAD_H
21 #define LOGDATAWORKERTHREAD_H
22 
23 #include <QObject>
24 #include <QThread>
25 #include <QMutex>
26 #include <QWaitCondition>
27 #include <QVector>
28 
29 #include "loadingstatus.h"
30 #include "linepositionarray.h"
31 #include "encodingspeculator.h"
32 #include "utils.h"
33 
34 // This class is a thread-safe set of indexing data.
35 class IndexingData
36 {
37   public:
IndexingData()38     IndexingData() : dataMutex_(), linePosition_(), maxLength_(0),
39         indexedSize_(0), encoding_(EncodingSpeculator::Encoding::ASCII7) { }
40 
41     // Get the total indexed size
42     qint64 getSize() const;
43 
44     // Get the length of the longest line
45     int getMaxLength() const;
46 
47     // Get the total number of lines
48     LineNumber getNbLines() const;
49 
50     // Get the position (in byte from the beginning of the file)
51     // of the end of the passed line.
52     qint64 getPosForLine( LineNumber line ) const;
53 
54     // Get the guessed encoding for the content.
55     EncodingSpeculator::Encoding getEncodingGuess() const;
56 
57     // Atomically add to all the existing
58     // indexing data.
59     void addAll( qint64 size, int length,
60             const FastLinePositionArray& linePosition,
61             EncodingSpeculator::Encoding encoding );
62 
63     // Completely clear the indexing data.
64     void clear();
65 
66   private:
67     mutable QMutex dataMutex_;
68 
69     LinePositionArray linePosition_;
70     int maxLength_;
71     qint64 indexedSize_;
72 
73     EncodingSpeculator::Encoding encoding_;
74 };
75 
76 class IndexOperation : public QObject
77 {
78   Q_OBJECT
79   public:
80     IndexOperation( const QString& fileName,
81             IndexingData* indexingData, bool* interruptRequest,
82             EncodingSpeculator* encodingSpeculator );
83 
~IndexOperation()84     virtual ~IndexOperation() { }
85 
86     // Start the indexing operation, returns true if it has been done
87     // and false if it has been cancelled (results not copied)
88     virtual bool start() = 0;
89 
90   signals:
91     void indexingProgressed( int );
92 
93   protected:
94     static const int sizeChunk;
95 
96     // Returns the total size indexed
97     // Modify the passed linePosition and maxLength
98     void doIndex( IndexingData* linePosition, EncodingSpeculator* encodingSpeculator,
99             qint64 initialPosition );
100 
101     QString fileName_;
102     bool* interruptRequest_;
103     IndexingData* indexing_data_;
104 
105     EncodingSpeculator* encoding_speculator_;
106 };
107 
108 class FullIndexOperation : public IndexOperation
109 {
110   public:
FullIndexOperation(const QString & fileName,IndexingData * indexingData,bool * interruptRequest,EncodingSpeculator * speculator)111     FullIndexOperation( const QString& fileName,
112             IndexingData* indexingData, bool* interruptRequest,
113             EncodingSpeculator* speculator )
114         : IndexOperation( fileName, indexingData, interruptRequest, speculator ) { }
115     virtual bool start();
116 };
117 
118 class PartialIndexOperation : public IndexOperation
119 {
120   public:
PartialIndexOperation(const QString & fileName,IndexingData * indexingData,bool * interruptRequest,EncodingSpeculator * speculator)121     PartialIndexOperation( const QString& fileName,
122             IndexingData* indexingData, bool* interruptRequest,
123             EncodingSpeculator* speculator )
124         : IndexOperation( fileName, indexingData, interruptRequest, speculator ) { }
125     virtual bool start();
126 };
127 
128 // Create and manage the thread doing loading/indexing for
129 // the creating LogData. One LogDataWorkerThread is used
130 // per LogData instance.
131 // Note everything except the run() function is in the LogData's
132 // thread.
133 class LogDataWorkerThread : public QThread
134 {
135   Q_OBJECT
136 
137   public:
138     // Pass a pointer to the IndexingData (initially empty)
139     // This object will change it when indexing (IndexingData must be thread safe!)
140     LogDataWorkerThread( IndexingData* indexing_data );
141     ~LogDataWorkerThread();
142 
143     // Attaches to a file on disk. Attaching to a non existant file
144     // will work, it will just appear as an empty file.
145     void attachFile( const QString& fileName );
146     // Instructs the thread to start a new full indexing of the file, sending
147     // signals as it progresses.
148     void indexAll();
149     // Instructs the thread to start a partial indexing (starting at
150     // the end of the file as indexed).
151     void indexAdditionalLines();
152     // Interrupts the indexing if one is in progress
153     void interrupt();
154 
155     // Returns a copy of the current indexing data
156     void getIndexingData( qint64* indexedSize,
157             int* maxLength, LinePositionArray* linePosition );
158 
159   signals:
160     // Sent during the indexing process to signal progress
161     // percent being the percentage of completion.
162     void indexingProgressed( int percent );
163     // Sent when indexing is finished, signals the client
164     // to copy the new data back.
165     void indexingFinished( LoadingStatus status );
166 
167   protected:
168     void run();
169 
170   private:
171     void doIndexAll();
172 
173     // Mutex to protect operationRequested_ and friends
174     QMutex mutex_;
175     QWaitCondition operationRequestedCond_;
176     QWaitCondition nothingToDoCond_;
177     QString fileName_;
178 
179     // Set when the thread must die
180     bool terminate_;
181     bool interruptRequested_;
182     IndexOperation* operationRequested_;
183 
184     // Pointer to the owner's indexing data (we modify it)
185     IndexingData* indexing_data_;
186 
187     // To guess the encoding
188     EncodingSpeculator encodingSpeculator_;
189 };
190 
191 #endif
192