xref: /glogg/src/data/logdataworkerthread.h (revision 3c46a4695c48e83de2b8042a54c32333a43a44eb) !
1 /*
2  * Copyright (C) 2009, 2010, 2014 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 
32 // This class is a mutex protected set of indexing data.
33 // It is thread safe.
34 class IndexingData
35 {
36   public:
37     IndexingData() : dataMutex_(), linePosition_(), maxLength_(0), indexedSize_(0) { }
38 
39     // Atomically get all the indexing data
40     void getAll( qint64* size, int* length,
41             LinePositionArray* linePosition );
42 
43     // Atomically set all the indexing data
44     // (overwriting the existing, linePosition is moved)
45     void setAll( qint64 size, int length,
46             LinePositionArray& linePosition );
47 
48     // Atomically add to all the existing
49     // indexing data.
50     void addAll( qint64 size, int length,
51             const LinePositionArray& linePosition );
52 
53   private:
54     QMutex dataMutex_;
55 
56     LinePositionArray linePosition_;
57     int maxLength_;
58     qint64 indexedSize_;
59 };
60 
61 class IndexOperation : public QObject
62 {
63   Q_OBJECT
64   public:
65     IndexOperation( QString& fileName, bool* interruptRequest );
66 
67     virtual ~IndexOperation() { }
68 
69     // Start the indexing operation, returns true if it has been done
70     // and false if it has been cancelled (results not copied)
71     virtual bool start( IndexingData& result ) = 0;
72 
73   signals:
74     void indexingProgressed( int );
75 
76   protected:
77     static const int sizeChunk;
78 
79     // Returns the total size indexed
80     qint64 doIndex( LinePositionArray& linePosition, int* maxLength,
81             qint64 initialPosition );
82 
83     QString fileName_;
84     bool* interruptRequest_;
85 };
86 
87 class FullIndexOperation : public IndexOperation
88 {
89   public:
90     FullIndexOperation( QString& fileName, bool* interruptRequest )
91         : IndexOperation( fileName, interruptRequest ) { }
92     virtual bool start( IndexingData& result );
93 };
94 
95 class PartialIndexOperation : public IndexOperation
96 {
97   public:
98     PartialIndexOperation( QString& fileName, bool* interruptRequest, qint64 position );
99     virtual bool start( IndexingData& result );
100 
101   private:
102     qint64 initialPosition_;
103 };
104 
105 // Create and manage the thread doing loading/indexing for
106 // the creating LogData. One LogDataWorkerThread is used
107 // per LogData instance.
108 // Note everything except the run() function is in the LogData's
109 // thread.
110 class LogDataWorkerThread : public QThread
111 {
112   Q_OBJECT
113 
114   public:
115     LogDataWorkerThread();
116     ~LogDataWorkerThread();
117 
118     // Attaches to a file on disk. Attaching to a non existant file
119     // will work, it will just appear as an empty file.
120     void attachFile( const QString& fileName );
121     // Instructs the thread to start a new full indexing of the file, sending
122     // signals as it progresses.
123     void indexAll();
124     // Instructs the thread to start a partial indexing (starting at
125     // the index passed).
126     void indexAdditionalLines( qint64 position );
127     // Interrupts the indexing if one is in progress
128     void interrupt();
129 
130     // Returns a copy of the current indexing data
131     void getIndexingData( qint64* indexedSize,
132             int* maxLength, LinePositionArray* linePosition );
133 
134   signals:
135     // Sent during the indexing process to signal progress
136     // percent being the percentage of completion.
137     void indexingProgressed( int percent );
138     // Sent when indexing is finished, signals the client
139     // to copy the new data back.
140     void indexingFinished( LoadingStatus status );
141 
142   protected:
143     void run();
144 
145   private:
146     void doIndexAll();
147 
148     // Mutex to protect operationRequested_ and friends
149     QMutex mutex_;
150     QWaitCondition operationRequestedCond_;
151     QWaitCondition nothingToDoCond_;
152     QString fileName_;
153 
154     // Set when the thread must die
155     bool terminate_;
156     bool interruptRequested_;
157     IndexOperation* operationRequested_;
158 
159     // Shared indexing data
160     IndexingData indexingData_;
161 };
162 
163 #endif
164