xref: /glogg/src/data/logdataworkerthread.h (revision de1abac61b191ce1317b0ceaa43904b8f2fb2bd3)
1bb02e0acSNicolas Bonnefon /*
2e49f4922SNicolas Bonnefon  * Copyright (C) 2009, 2010, 2014, 2015 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 LOGDATAWORKERTHREAD_H
21bb02e0acSNicolas Bonnefon #define LOGDATAWORKERTHREAD_H
22bb02e0acSNicolas Bonnefon 
23bb02e0acSNicolas Bonnefon #include <QObject>
24bb02e0acSNicolas Bonnefon #include <QThread>
25bb02e0acSNicolas Bonnefon #include <QMutex>
26bb02e0acSNicolas Bonnefon #include <QWaitCondition>
27bb02e0acSNicolas Bonnefon #include <QVector>
28bb02e0acSNicolas Bonnefon 
29812146a8SNicolas Bonnefon #include "loadingstatus.h"
30f049f87fSNicolas Bonnefon #include "linepositionarray.h"
315fa25391SNicolas Bonnefon #include "encodingspeculator.h"
322493b508SNicolas Bonnefon #include "utils.h"
33653377b6SNicolas Bonnefon 
34653377b6SNicolas Bonnefon // This class is a thread-safe set of indexing data.
35bb02e0acSNicolas Bonnefon class IndexingData
36bb02e0acSNicolas Bonnefon {
37bb02e0acSNicolas Bonnefon   public:
IndexingData()385fa25391SNicolas Bonnefon     IndexingData() : dataMutex_(), linePosition_(), maxLength_(0),
395fa25391SNicolas Bonnefon         indexedSize_(0), encoding_(EncodingSpeculator::Encoding::ASCII7) { }
40bb02e0acSNicolas Bonnefon 
41653377b6SNicolas Bonnefon     // Get the total indexed size
42653377b6SNicolas Bonnefon     qint64 getSize() const;
43653377b6SNicolas Bonnefon 
44653377b6SNicolas Bonnefon     // Get the length of the longest line
45653377b6SNicolas Bonnefon     int getMaxLength() const;
46653377b6SNicolas Bonnefon 
47653377b6SNicolas Bonnefon     // Get the total number of lines
48653377b6SNicolas Bonnefon     LineNumber getNbLines() const;
49653377b6SNicolas Bonnefon 
50653377b6SNicolas Bonnefon     // Get the position (in byte from the beginning of the file)
51653377b6SNicolas Bonnefon     // of the end of the passed line.
52653377b6SNicolas Bonnefon     qint64 getPosForLine( LineNumber line ) const;
53bb02e0acSNicolas Bonnefon 
545fa25391SNicolas Bonnefon     // Get the guessed encoding for the content.
555fa25391SNicolas Bonnefon     EncodingSpeculator::Encoding getEncodingGuess() const;
565fa25391SNicolas Bonnefon 
57bb02e0acSNicolas Bonnefon     // Atomically add to all the existing
58bb02e0acSNicolas Bonnefon     // indexing data.
59bb02e0acSNicolas Bonnefon     void addAll( qint64 size, int length,
605fa25391SNicolas Bonnefon             const FastLinePositionArray& linePosition,
615fa25391SNicolas Bonnefon             EncodingSpeculator::Encoding encoding );
62653377b6SNicolas Bonnefon 
63653377b6SNicolas Bonnefon     // Completely clear the indexing data.
64653377b6SNicolas Bonnefon     void clear();
65bb02e0acSNicolas Bonnefon 
66bb02e0acSNicolas Bonnefon   private:
67653377b6SNicolas Bonnefon     mutable QMutex dataMutex_;
68bb02e0acSNicolas Bonnefon 
69bb02e0acSNicolas Bonnefon     LinePositionArray linePosition_;
70bb02e0acSNicolas Bonnefon     int maxLength_;
71bb02e0acSNicolas Bonnefon     qint64 indexedSize_;
725fa25391SNicolas Bonnefon 
735fa25391SNicolas Bonnefon     EncodingSpeculator::Encoding encoding_;
74bb02e0acSNicolas Bonnefon };
75bb02e0acSNicolas Bonnefon 
76bb02e0acSNicolas Bonnefon class IndexOperation : public QObject
77bb02e0acSNicolas Bonnefon {
78bb02e0acSNicolas Bonnefon   Q_OBJECT
79bb02e0acSNicolas Bonnefon   public:
80653377b6SNicolas Bonnefon     IndexOperation( const QString& fileName,
815fa25391SNicolas Bonnefon             IndexingData* indexingData, bool* interruptRequest,
825fa25391SNicolas Bonnefon             EncodingSpeculator* encodingSpeculator );
83bb02e0acSNicolas Bonnefon 
~IndexOperation()84bb02e0acSNicolas Bonnefon     virtual ~IndexOperation() { }
85bb02e0acSNicolas Bonnefon 
86bb02e0acSNicolas Bonnefon     // Start the indexing operation, returns true if it has been done
87bb02e0acSNicolas Bonnefon     // and false if it has been cancelled (results not copied)
88653377b6SNicolas Bonnefon     virtual bool start() = 0;
89bb02e0acSNicolas Bonnefon 
90bb02e0acSNicolas Bonnefon   signals:
91bb02e0acSNicolas Bonnefon     void indexingProgressed( int );
92bb02e0acSNicolas Bonnefon 
93bb02e0acSNicolas Bonnefon   protected:
94bb02e0acSNicolas Bonnefon     static const int sizeChunk;
95bb02e0acSNicolas Bonnefon 
96bb02e0acSNicolas Bonnefon     // Returns the total size indexed
97653377b6SNicolas Bonnefon     // Modify the passed linePosition and maxLength
985fa25391SNicolas Bonnefon     void doIndex( IndexingData* linePosition, EncodingSpeculator* encodingSpeculator,
995fa25391SNicolas Bonnefon             qint64 initialPosition );
100bb02e0acSNicolas Bonnefon 
101bb02e0acSNicolas Bonnefon     QString fileName_;
102bb02e0acSNicolas Bonnefon     bool* interruptRequest_;
103653377b6SNicolas Bonnefon     IndexingData* indexing_data_;
1045fa25391SNicolas Bonnefon 
1055fa25391SNicolas Bonnefon     EncodingSpeculator* encoding_speculator_;
106bb02e0acSNicolas Bonnefon };
107bb02e0acSNicolas Bonnefon 
108bb02e0acSNicolas Bonnefon class FullIndexOperation : public IndexOperation
109bb02e0acSNicolas Bonnefon {
110bb02e0acSNicolas Bonnefon   public:
FullIndexOperation(const QString & fileName,IndexingData * indexingData,bool * interruptRequest,EncodingSpeculator * speculator)111653377b6SNicolas Bonnefon     FullIndexOperation( const QString& fileName,
1125fa25391SNicolas Bonnefon             IndexingData* indexingData, bool* interruptRequest,
1135fa25391SNicolas Bonnefon             EncodingSpeculator* speculator )
1145fa25391SNicolas Bonnefon         : IndexOperation( fileName, indexingData, interruptRequest, speculator ) { }
115653377b6SNicolas Bonnefon     virtual bool start();
116bb02e0acSNicolas Bonnefon };
117bb02e0acSNicolas Bonnefon 
118bb02e0acSNicolas Bonnefon class PartialIndexOperation : public IndexOperation
119bb02e0acSNicolas Bonnefon {
120bb02e0acSNicolas Bonnefon   public:
PartialIndexOperation(const QString & fileName,IndexingData * indexingData,bool * interruptRequest,EncodingSpeculator * speculator)121*de1abac6SNicolas Bonnefon     PartialIndexOperation( const QString& fileName,
122*de1abac6SNicolas Bonnefon             IndexingData* indexingData, bool* interruptRequest,
123*de1abac6SNicolas Bonnefon             EncodingSpeculator* speculator )
124*de1abac6SNicolas Bonnefon         : IndexOperation( fileName, indexingData, interruptRequest, speculator ) { }
125653377b6SNicolas Bonnefon     virtual bool start();
126bb02e0acSNicolas Bonnefon };
127bb02e0acSNicolas Bonnefon 
128bb02e0acSNicolas Bonnefon // Create and manage the thread doing loading/indexing for
129bb02e0acSNicolas Bonnefon // the creating LogData. One LogDataWorkerThread is used
130bb02e0acSNicolas Bonnefon // per LogData instance.
131bb02e0acSNicolas Bonnefon // Note everything except the run() function is in the LogData's
132bb02e0acSNicolas Bonnefon // thread.
133bb02e0acSNicolas Bonnefon class LogDataWorkerThread : public QThread
134bb02e0acSNicolas Bonnefon {
135bb02e0acSNicolas Bonnefon   Q_OBJECT
136bb02e0acSNicolas Bonnefon 
137bb02e0acSNicolas Bonnefon   public:
138653377b6SNicolas Bonnefon     // Pass a pointer to the IndexingData (initially empty)
139653377b6SNicolas Bonnefon     // This object will change it when indexing (IndexingData must be thread safe!)
140653377b6SNicolas Bonnefon     LogDataWorkerThread( IndexingData* indexing_data );
141bb02e0acSNicolas Bonnefon     ~LogDataWorkerThread();
142bb02e0acSNicolas Bonnefon 
143bb02e0acSNicolas Bonnefon     // Attaches to a file on disk. Attaching to a non existant file
144bb02e0acSNicolas Bonnefon     // will work, it will just appear as an empty file.
145bb02e0acSNicolas Bonnefon     void attachFile( const QString& fileName );
146bb02e0acSNicolas Bonnefon     // Instructs the thread to start a new full indexing of the file, sending
147bb02e0acSNicolas Bonnefon     // signals as it progresses.
148bb02e0acSNicolas Bonnefon     void indexAll();
149bb02e0acSNicolas Bonnefon     // Instructs the thread to start a partial indexing (starting at
150*de1abac6SNicolas Bonnefon     // the end of the file as indexed).
151*de1abac6SNicolas Bonnefon     void indexAdditionalLines();
152bb02e0acSNicolas Bonnefon     // Interrupts the indexing if one is in progress
153bb02e0acSNicolas Bonnefon     void interrupt();
154bb02e0acSNicolas Bonnefon 
155bb02e0acSNicolas Bonnefon     // Returns a copy of the current indexing data
156bb02e0acSNicolas Bonnefon     void getIndexingData( qint64* indexedSize,
157bb02e0acSNicolas Bonnefon             int* maxLength, LinePositionArray* linePosition );
158bb02e0acSNicolas Bonnefon 
159bb02e0acSNicolas Bonnefon   signals:
160bb02e0acSNicolas Bonnefon     // Sent during the indexing process to signal progress
161bb02e0acSNicolas Bonnefon     // percent being the percentage of completion.
162bb02e0acSNicolas Bonnefon     void indexingProgressed( int percent );
163bb02e0acSNicolas Bonnefon     // Sent when indexing is finished, signals the client
164bb02e0acSNicolas Bonnefon     // to copy the new data back.
165812146a8SNicolas Bonnefon     void indexingFinished( LoadingStatus status );
166bb02e0acSNicolas Bonnefon 
167bb02e0acSNicolas Bonnefon   protected:
168bb02e0acSNicolas Bonnefon     void run();
169bb02e0acSNicolas Bonnefon 
170bb02e0acSNicolas Bonnefon   private:
171bb02e0acSNicolas Bonnefon     void doIndexAll();
172bb02e0acSNicolas Bonnefon 
173bb02e0acSNicolas Bonnefon     // Mutex to protect operationRequested_ and friends
174bb02e0acSNicolas Bonnefon     QMutex mutex_;
175bb02e0acSNicolas Bonnefon     QWaitCondition operationRequestedCond_;
176bb02e0acSNicolas Bonnefon     QWaitCondition nothingToDoCond_;
177bb02e0acSNicolas Bonnefon     QString fileName_;
178bb02e0acSNicolas Bonnefon 
179bb02e0acSNicolas Bonnefon     // Set when the thread must die
180bb02e0acSNicolas Bonnefon     bool terminate_;
181bb02e0acSNicolas Bonnefon     bool interruptRequested_;
182bb02e0acSNicolas Bonnefon     IndexOperation* operationRequested_;
183bb02e0acSNicolas Bonnefon 
184653377b6SNicolas Bonnefon     // Pointer to the owner's indexing data (we modify it)
185653377b6SNicolas Bonnefon     IndexingData* indexing_data_;
1865fa25391SNicolas Bonnefon 
1875fa25391SNicolas Bonnefon     // To guess the encoding
1885fa25391SNicolas Bonnefon     EncodingSpeculator encodingSpeculator_;
189bb02e0acSNicolas Bonnefon };
190bb02e0acSNicolas Bonnefon 
191bb02e0acSNicolas Bonnefon #endif
192