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