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