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 32 // Line number are unsigned 32 bits for now. 33 typedef uint32_t LineNumber; 34 35 // This class is a thread-safe set of indexing data. 36 class IndexingData 37 { 38 public: 39 IndexingData() : dataMutex_(), linePosition_(), maxLength_(0), indexedSize_(0) { } 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 // Atomically add to all the existing 55 // indexing data. 56 void addAll( qint64 size, int length, 57 const FastLinePositionArray& linePosition ); 58 59 // Completely clear the indexing data. 60 void clear(); 61 62 private: 63 mutable QMutex dataMutex_; 64 65 LinePositionArray linePosition_; 66 int maxLength_; 67 qint64 indexedSize_; 68 }; 69 70 class IndexOperation : public QObject 71 { 72 Q_OBJECT 73 public: 74 IndexOperation( const QString& fileName, 75 IndexingData* indexingData, bool* interruptRequest ); 76 77 virtual ~IndexOperation() { } 78 79 // Start the indexing operation, returns true if it has been done 80 // and false if it has been cancelled (results not copied) 81 virtual bool start() = 0; 82 83 signals: 84 void indexingProgressed( int ); 85 86 protected: 87 static const int sizeChunk; 88 89 // Returns the total size indexed 90 // Modify the passed linePosition and maxLength 91 void doIndex( IndexingData* linePosition, qint64 initialPosition ); 92 93 QString fileName_; 94 bool* interruptRequest_; 95 IndexingData* indexing_data_; 96 }; 97 98 class FullIndexOperation : public IndexOperation 99 { 100 public: 101 FullIndexOperation( const QString& fileName, 102 IndexingData* indexingData, bool* interruptRequest ) 103 : IndexOperation( fileName, indexingData, interruptRequest ) { } 104 virtual bool start(); 105 }; 106 107 class PartialIndexOperation : public IndexOperation 108 { 109 public: 110 PartialIndexOperation( const QString& fileName, IndexingData* indexingData, 111 bool* interruptRequest, qint64 position ); 112 virtual bool start(); 113 114 private: 115 qint64 initialPosition_; 116 }; 117 118 // Create and manage the thread doing loading/indexing for 119 // the creating LogData. One LogDataWorkerThread is used 120 // per LogData instance. 121 // Note everything except the run() function is in the LogData's 122 // thread. 123 class LogDataWorkerThread : public QThread 124 { 125 Q_OBJECT 126 127 public: 128 // Pass a pointer to the IndexingData (initially empty) 129 // This object will change it when indexing (IndexingData must be thread safe!) 130 LogDataWorkerThread( IndexingData* indexing_data ); 131 ~LogDataWorkerThread(); 132 133 // Attaches to a file on disk. Attaching to a non existant file 134 // will work, it will just appear as an empty file. 135 void attachFile( const QString& fileName ); 136 // Instructs the thread to start a new full indexing of the file, sending 137 // signals as it progresses. 138 void indexAll(); 139 // Instructs the thread to start a partial indexing (starting at 140 // the index passed). 141 void indexAdditionalLines( qint64 position ); 142 // Interrupts the indexing if one is in progress 143 void interrupt(); 144 145 // Returns a copy of the current indexing data 146 void getIndexingData( qint64* indexedSize, 147 int* maxLength, LinePositionArray* linePosition ); 148 149 signals: 150 // Sent during the indexing process to signal progress 151 // percent being the percentage of completion. 152 void indexingProgressed( int percent ); 153 // Sent when indexing is finished, signals the client 154 // to copy the new data back. 155 void indexingFinished( LoadingStatus status ); 156 157 protected: 158 void run(); 159 160 private: 161 void doIndexAll(); 162 163 // Mutex to protect operationRequested_ and friends 164 QMutex mutex_; 165 QWaitCondition operationRequestedCond_; 166 QWaitCondition nothingToDoCond_; 167 QString fileName_; 168 169 // Set when the thread must die 170 bool terminate_; 171 bool interruptRequested_; 172 IndexOperation* operationRequested_; 173 174 // Pointer to the owner's indexing data (we modify it) 175 IndexingData* indexing_data_; 176 }; 177 178 #endif 179