xref: /glogg/src/data/logfiltereddata.cpp (revision c59cadb3bc56e902de41bd6b429f9d7bc056088a)
1bb02e0acSNicolas Bonnefon /*
28e788202SNicolas Bonnefon  * Copyright (C) 2009, 2010, 2011, 2012, 2013, 2017 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 // This file implements LogFilteredData
21bb02e0acSNicolas Bonnefon // It stores a pointer to the LogData that created it,
22bb02e0acSNicolas Bonnefon // so should always be destroyed before the LogData.
23bb02e0acSNicolas Bonnefon 
24bb02e0acSNicolas Bonnefon #include "log.h"
25bb02e0acSNicolas Bonnefon 
26bb02e0acSNicolas Bonnefon #include <QString>
27bb02e0acSNicolas Bonnefon #include <cassert>
28bb02e0acSNicolas Bonnefon #include <limits>
29bb02e0acSNicolas Bonnefon 
30bb02e0acSNicolas Bonnefon #include "utils.h"
31bb02e0acSNicolas Bonnefon #include "logdata.h"
32bb02e0acSNicolas Bonnefon #include "marks.h"
33bb02e0acSNicolas Bonnefon #include "logfiltereddata.h"
34bb02e0acSNicolas Bonnefon 
35bb02e0acSNicolas Bonnefon // Creates an empty set. It must be possible to display it without error.
36bb02e0acSNicolas Bonnefon // FIXME
LogFilteredData()37bb02e0acSNicolas Bonnefon LogFilteredData::LogFilteredData() : AbstractLogData(),
38ced968a9SNicolas Bonnefon     matching_lines_(),
39bb02e0acSNicolas Bonnefon     currentRegExp_(),
40bb02e0acSNicolas Bonnefon     visibility_(),
41ef13a493SNicolas Bonnefon     filteredItemsCache_(),
42ef13a493SNicolas Bonnefon     workerThread_( nullptr ),
43ced968a9SNicolas Bonnefon     marks_()
44bb02e0acSNicolas Bonnefon {
45bb02e0acSNicolas Bonnefon     /* Prevent any more searching */
46bb02e0acSNicolas Bonnefon     maxLength_ = 0;
47bb02e0acSNicolas Bonnefon     maxLengthMarks_ = 0;
48bb02e0acSNicolas Bonnefon     searchDone_ = true;
49bb02e0acSNicolas Bonnefon     visibility_ = MarksAndMatches;
50bb02e0acSNicolas Bonnefon 
51bb02e0acSNicolas Bonnefon     filteredItemsCacheDirty_ = true;
52bb02e0acSNicolas Bonnefon }
53bb02e0acSNicolas Bonnefon 
54bb02e0acSNicolas Bonnefon // Usual constructor: just copy the data, the search is started by runSearch()
LogFilteredData(const LogData * logData)55bb02e0acSNicolas Bonnefon LogFilteredData::LogFilteredData( const LogData* logData )
56bb02e0acSNicolas Bonnefon     : AbstractLogData(),
57ced968a9SNicolas Bonnefon     matching_lines_( SearchResultArray() ),
58bb02e0acSNicolas Bonnefon     currentRegExp_(),
59bb02e0acSNicolas Bonnefon     visibility_(),
60ef13a493SNicolas Bonnefon     filteredItemsCache_(),
61ef13a493SNicolas Bonnefon     workerThread_( logData ),
62ced968a9SNicolas Bonnefon     marks_()
63bb02e0acSNicolas Bonnefon {
64bb02e0acSNicolas Bonnefon     // Starts with an empty result list
65bb02e0acSNicolas Bonnefon     maxLength_ = 0;
66bb02e0acSNicolas Bonnefon     maxLengthMarks_ = 0;
67bb02e0acSNicolas Bonnefon     nbLinesProcessed_ = 0;
68bb02e0acSNicolas Bonnefon 
69bb02e0acSNicolas Bonnefon     sourceLogData_ = logData;
70bb02e0acSNicolas Bonnefon 
71bb02e0acSNicolas Bonnefon     searchDone_ = false;
72bb02e0acSNicolas Bonnefon 
73bb02e0acSNicolas Bonnefon     visibility_ = MarksAndMatches;
74bb02e0acSNicolas Bonnefon 
75bb02e0acSNicolas Bonnefon     filteredItemsCacheDirty_ = true;
76bb02e0acSNicolas Bonnefon 
77bb02e0acSNicolas Bonnefon     // Forward the update signal
78*c59cadb3SNicolas Bonnefon     connect( &workerThread_, SIGNAL( searchProgressed( int, int, qint64 ) ),
79*c59cadb3SNicolas Bonnefon             this, SLOT( handleSearchProgressed( int, int, qint64 ) ) );
80bb02e0acSNicolas Bonnefon 
81bb02e0acSNicolas Bonnefon     // Starts the worker thread
82ef13a493SNicolas Bonnefon     workerThread_.start();
83ef13a493SNicolas Bonnefon }
84ef13a493SNicolas Bonnefon 
~LogFilteredData()85ef13a493SNicolas Bonnefon LogFilteredData::~LogFilteredData()
86ef13a493SNicolas Bonnefon {
87ef13a493SNicolas Bonnefon     // FIXME
88ef13a493SNicolas Bonnefon     // workerThread_.stop();
89bb02e0acSNicolas Bonnefon }
90bb02e0acSNicolas Bonnefon 
91bb02e0acSNicolas Bonnefon //
92bb02e0acSNicolas Bonnefon // Public functions
93bb02e0acSNicolas Bonnefon //
94bb02e0acSNicolas Bonnefon 
95bb02e0acSNicolas Bonnefon // Run the search and send newDataAvailable() signals.
runSearch(const QRegularExpression & regExp)964fb0346eSAnton Filimonov void LogFilteredData::runSearch( const QRegularExpression& regExp )
97bb02e0acSNicolas Bonnefon {
98bb02e0acSNicolas Bonnefon     LOG(logDEBUG) << "Entering runSearch";
99bb02e0acSNicolas Bonnefon 
100721a2433SNicolas Bonnefon     clearSearch();
101bb02e0acSNicolas Bonnefon     currentRegExp_ = regExp;
102bb02e0acSNicolas Bonnefon 
103ef13a493SNicolas Bonnefon     workerThread_.search( currentRegExp_ );
104bb02e0acSNicolas Bonnefon }
105bb02e0acSNicolas Bonnefon 
updateSearch()106bb02e0acSNicolas Bonnefon void LogFilteredData::updateSearch()
107bb02e0acSNicolas Bonnefon {
108bb02e0acSNicolas Bonnefon     LOG(logDEBUG) << "Entering updateSearch";
109bb02e0acSNicolas Bonnefon 
110ef13a493SNicolas Bonnefon     workerThread_.updateSearch( currentRegExp_, nbLinesProcessed_ );
111bb02e0acSNicolas Bonnefon }
112bb02e0acSNicolas Bonnefon 
interruptSearch()113bb02e0acSNicolas Bonnefon void LogFilteredData::interruptSearch()
114bb02e0acSNicolas Bonnefon {
115bb02e0acSNicolas Bonnefon     LOG(logDEBUG) << "Entering interruptSearch";
116bb02e0acSNicolas Bonnefon 
117ef13a493SNicolas Bonnefon     workerThread_.interrupt();
118bb02e0acSNicolas Bonnefon }
119bb02e0acSNicolas Bonnefon 
clearSearch()120bb02e0acSNicolas Bonnefon void LogFilteredData::clearSearch()
121bb02e0acSNicolas Bonnefon {
1224fb0346eSAnton Filimonov     currentRegExp_ = QRegularExpression();
123ced968a9SNicolas Bonnefon     matching_lines_.clear();
124bb02e0acSNicolas Bonnefon     maxLength_        = 0;
125721a2433SNicolas Bonnefon     nbLinesProcessed_ = 0;
126bb02e0acSNicolas Bonnefon     filteredItemsCacheDirty_ = true;
127bb02e0acSNicolas Bonnefon }
128bb02e0acSNicolas Bonnefon 
getMatchingLineNumber(int matchNum) const129bb02e0acSNicolas Bonnefon qint64 LogFilteredData::getMatchingLineNumber( int matchNum ) const
130bb02e0acSNicolas Bonnefon {
131bb02e0acSNicolas Bonnefon     qint64 matchingLine = findLogDataLine( matchNum );
132bb02e0acSNicolas Bonnefon 
133bb02e0acSNicolas Bonnefon     return matchingLine;
134bb02e0acSNicolas Bonnefon }
135bb02e0acSNicolas Bonnefon 
136bb02e0acSNicolas Bonnefon // Scan the list for the 'lineNumber' passed
isLineInMatchingList(qint64 lineNumber)137bb02e0acSNicolas Bonnefon bool LogFilteredData::isLineInMatchingList( qint64 lineNumber )
138bb02e0acSNicolas Bonnefon {
139bb02e0acSNicolas Bonnefon     int index;                                    // Not used
140bb02e0acSNicolas Bonnefon     return lookupLineNumber<SearchResultArray>(
141ced968a9SNicolas Bonnefon             matching_lines_, lineNumber, &index);
142bb02e0acSNicolas Bonnefon }
143bb02e0acSNicolas Bonnefon 
getLineIndexNumber(quint64 lineNumber) const1443ff6c941SAnton Filimonov int LogFilteredData::getLineIndexNumber( quint64 lineNumber ) const
1453ff6c941SAnton Filimonov {
1463ff6c941SAnton Filimonov     int lineIndex = findFilteredLine( lineNumber );
1473ff6c941SAnton Filimonov     return lineIndex;
1483ff6c941SAnton Filimonov }
149bb02e0acSNicolas Bonnefon 
getNbTotalLines() const150ced968a9SNicolas Bonnefon LineNumber LogFilteredData::getNbTotalLines() const
151bb02e0acSNicolas Bonnefon {
152bb02e0acSNicolas Bonnefon     return sourceLogData_->getNbLine();
153bb02e0acSNicolas Bonnefon }
154bb02e0acSNicolas Bonnefon 
getNbMatches() const155ced968a9SNicolas Bonnefon LineNumber LogFilteredData::getNbMatches() const
156bb02e0acSNicolas Bonnefon {
157ced968a9SNicolas Bonnefon     return matching_lines_.size();
158bb02e0acSNicolas Bonnefon }
159bb02e0acSNicolas Bonnefon 
getNbMarks() const160ced968a9SNicolas Bonnefon LineNumber LogFilteredData::getNbMarks() const
161bb02e0acSNicolas Bonnefon {
162ced968a9SNicolas Bonnefon     return marks_.size();
163bb02e0acSNicolas Bonnefon }
164bb02e0acSNicolas Bonnefon 
165bb02e0acSNicolas Bonnefon LogFilteredData::FilteredLineType
filteredLineTypeByIndex(int index) const166bb02e0acSNicolas Bonnefon     LogFilteredData::filteredLineTypeByIndex( int index ) const
167bb02e0acSNicolas Bonnefon {
168bb02e0acSNicolas Bonnefon     // If we are only showing one type, the line is there because
169bb02e0acSNicolas Bonnefon     // it is of this type.
170bb02e0acSNicolas Bonnefon     if ( visibility_ == MatchesOnly )
171bb02e0acSNicolas Bonnefon         return Match;
172bb02e0acSNicolas Bonnefon     else if ( visibility_ == MarksOnly )
173bb02e0acSNicolas Bonnefon         return Mark;
174bb02e0acSNicolas Bonnefon     else {
175bb02e0acSNicolas Bonnefon         // If it is MarksAndMatches, we have to look.
176bb02e0acSNicolas Bonnefon         // Regenerate the cache if needed
177bb02e0acSNicolas Bonnefon         if ( filteredItemsCacheDirty_ )
178bb02e0acSNicolas Bonnefon             regenerateFilteredItemsCache();
179bb02e0acSNicolas Bonnefon 
180bb02e0acSNicolas Bonnefon         return filteredItemsCache_[ index ].type();
181bb02e0acSNicolas Bonnefon     }
182bb02e0acSNicolas Bonnefon }
183bb02e0acSNicolas Bonnefon 
184bb02e0acSNicolas Bonnefon // Delegation to our Marks object
185bb02e0acSNicolas Bonnefon 
addMark(qint64 line,QChar mark)186bb02e0acSNicolas Bonnefon void LogFilteredData::addMark( qint64 line, QChar mark )
187bb02e0acSNicolas Bonnefon {
188bb02e0acSNicolas Bonnefon     if ( ( line >= 0 ) && ( line < sourceLogData_->getNbLine() ) ) {
189ced968a9SNicolas Bonnefon         marks_.addMark( line, mark );
190bb02e0acSNicolas Bonnefon         maxLengthMarks_ = qMax( maxLengthMarks_,
191bb02e0acSNicolas Bonnefon                 sourceLogData_->getLineLength( line ) );
192bb02e0acSNicolas Bonnefon         filteredItemsCacheDirty_ = true;
193bb02e0acSNicolas Bonnefon     }
194bb02e0acSNicolas Bonnefon     else
195bb02e0acSNicolas Bonnefon         LOG(logERROR) << "LogFilteredData::addMark\
196bb02e0acSNicolas Bonnefon  trying to create a mark outside of the file.";
197bb02e0acSNicolas Bonnefon }
198bb02e0acSNicolas Bonnefon 
getMark(QChar mark) const199bb02e0acSNicolas Bonnefon qint64 LogFilteredData::getMark( QChar mark ) const
200bb02e0acSNicolas Bonnefon {
201ced968a9SNicolas Bonnefon     return marks_.getMark( mark );
202bb02e0acSNicolas Bonnefon }
203bb02e0acSNicolas Bonnefon 
isLineMarked(qint64 line) const204bb02e0acSNicolas Bonnefon bool LogFilteredData::isLineMarked( qint64 line ) const
205bb02e0acSNicolas Bonnefon {
206ced968a9SNicolas Bonnefon     return marks_.isLineMarked( line );
207bb02e0acSNicolas Bonnefon }
208bb02e0acSNicolas Bonnefon 
getMarkAfter(qint64 line) const2098e788202SNicolas Bonnefon qint64 LogFilteredData::getMarkAfter( qint64 line ) const
2108e788202SNicolas Bonnefon {
2118e788202SNicolas Bonnefon     qint64 marked_line = -1;
2128e788202SNicolas Bonnefon 
2138e788202SNicolas Bonnefon     for ( auto i = marks_.begin(); i != marks_.end(); ++i ) {
2148e788202SNicolas Bonnefon         if ( i->lineNumber() > line ) {
2158e788202SNicolas Bonnefon             marked_line = i->lineNumber();
2168e788202SNicolas Bonnefon             break;
2178e788202SNicolas Bonnefon         }
2188e788202SNicolas Bonnefon     }
2198e788202SNicolas Bonnefon 
2208e788202SNicolas Bonnefon     return marked_line;
2218e788202SNicolas Bonnefon }
2228e788202SNicolas Bonnefon 
getMarkBefore(qint64 line) const2238e788202SNicolas Bonnefon qint64 LogFilteredData::getMarkBefore( qint64 line ) const
2248e788202SNicolas Bonnefon {
2258e788202SNicolas Bonnefon     qint64 marked_line = -1;
2268e788202SNicolas Bonnefon 
2278e788202SNicolas Bonnefon     for ( auto i = marks_.begin(); i != marks_.end(); ++i ) {
2288e788202SNicolas Bonnefon         if ( i->lineNumber() >= line ) {
2298e788202SNicolas Bonnefon             break;
2308e788202SNicolas Bonnefon         }
2318e788202SNicolas Bonnefon         marked_line = i->lineNumber();
2328e788202SNicolas Bonnefon     }
2338e788202SNicolas Bonnefon 
2348e788202SNicolas Bonnefon     return marked_line;
2358e788202SNicolas Bonnefon }
2368e788202SNicolas Bonnefon 
deleteMark(QChar mark)237bb02e0acSNicolas Bonnefon void LogFilteredData::deleteMark( QChar mark )
238bb02e0acSNicolas Bonnefon {
239ced968a9SNicolas Bonnefon     marks_.deleteMark( mark );
240bb02e0acSNicolas Bonnefon     filteredItemsCacheDirty_ = true;
241bb02e0acSNicolas Bonnefon 
242bb02e0acSNicolas Bonnefon     // FIXME: maxLengthMarks_
243bb02e0acSNicolas Bonnefon }
244bb02e0acSNicolas Bonnefon 
deleteMark(qint64 line)245bb02e0acSNicolas Bonnefon void LogFilteredData::deleteMark( qint64 line )
246bb02e0acSNicolas Bonnefon {
247ced968a9SNicolas Bonnefon     marks_.deleteMark( line );
248bb02e0acSNicolas Bonnefon     filteredItemsCacheDirty_ = true;
249bb02e0acSNicolas Bonnefon 
250bb02e0acSNicolas Bonnefon     // Now update the max length if needed
251bb02e0acSNicolas Bonnefon     if ( sourceLogData_->getLineLength( line ) >= maxLengthMarks_ ) {
252bb02e0acSNicolas Bonnefon         LOG(logDEBUG) << "deleteMark recalculating longest mark";
253bb02e0acSNicolas Bonnefon         maxLengthMarks_ = 0;
254ced968a9SNicolas Bonnefon         for ( Marks::const_iterator i = marks_.begin();
255ced968a9SNicolas Bonnefon                 i != marks_.end(); ++i ) {
256bb02e0acSNicolas Bonnefon             LOG(logDEBUG) << "line " << i->lineNumber();
257bb02e0acSNicolas Bonnefon             maxLengthMarks_ = qMax( maxLengthMarks_,
258bb02e0acSNicolas Bonnefon                     sourceLogData_->getLineLength( i->lineNumber() ) );
259bb02e0acSNicolas Bonnefon         }
260bb02e0acSNicolas Bonnefon     }
261bb02e0acSNicolas Bonnefon }
262bb02e0acSNicolas Bonnefon 
clearMarks()263bb02e0acSNicolas Bonnefon void LogFilteredData::clearMarks()
264bb02e0acSNicolas Bonnefon {
265ced968a9SNicolas Bonnefon     marks_.clear();
266bb02e0acSNicolas Bonnefon     filteredItemsCacheDirty_ = true;
267bb02e0acSNicolas Bonnefon     maxLengthMarks_ = 0;
268bb02e0acSNicolas Bonnefon }
269bb02e0acSNicolas Bonnefon 
setVisibility(Visibility visi)270bb02e0acSNicolas Bonnefon void LogFilteredData::setVisibility( Visibility visi )
271bb02e0acSNicolas Bonnefon {
272bb02e0acSNicolas Bonnefon     visibility_ = visi;
273bb02e0acSNicolas Bonnefon }
274bb02e0acSNicolas Bonnefon 
275bb02e0acSNicolas Bonnefon //
276bb02e0acSNicolas Bonnefon // Slots
277bb02e0acSNicolas Bonnefon //
handleSearchProgressed(int nbMatches,int progress,qint64 initial_position)278*c59cadb3SNicolas Bonnefon void LogFilteredData::handleSearchProgressed( int nbMatches, int progress, qint64 initial_position )
279bb02e0acSNicolas Bonnefon {
280bb02e0acSNicolas Bonnefon     LOG(logDEBUG) << "LogFilteredData::handleSearchProgressed matches="
281bb02e0acSNicolas Bonnefon         << nbMatches << " progress=" << progress;
282bb02e0acSNicolas Bonnefon 
283bb02e0acSNicolas Bonnefon     // searchDone_ = true;
284ced968a9SNicolas Bonnefon     workerThread_.getSearchResult( &maxLength_, &matching_lines_, &nbLinesProcessed_ );
285bb02e0acSNicolas Bonnefon     filteredItemsCacheDirty_ = true;
286bb02e0acSNicolas Bonnefon 
287*c59cadb3SNicolas Bonnefon     emit searchProgressed( nbMatches, progress, initial_position );
288bb02e0acSNicolas Bonnefon }
289bb02e0acSNicolas Bonnefon 
findLogDataLine(LineNumber lineNum) const290ced968a9SNicolas Bonnefon LineNumber LogFilteredData::findLogDataLine( LineNumber lineNum ) const
291bb02e0acSNicolas Bonnefon {
2922493b508SNicolas Bonnefon     LineNumber line = std::numeric_limits<LineNumber>::max();
293bb02e0acSNicolas Bonnefon     if ( visibility_ == MatchesOnly ) {
294ced968a9SNicolas Bonnefon         if ( lineNum < matching_lines_.size() ) {
295ced968a9SNicolas Bonnefon             line = matching_lines_[lineNum].lineNumber();
296bb02e0acSNicolas Bonnefon         }
297bb02e0acSNicolas Bonnefon         else {
298bb02e0acSNicolas Bonnefon             LOG(logERROR) << "Index too big in LogFilteredData: " << lineNum;
299bb02e0acSNicolas Bonnefon         }
300bb02e0acSNicolas Bonnefon     }
301bb02e0acSNicolas Bonnefon     else if ( visibility_ == MarksOnly ) {
302ced968a9SNicolas Bonnefon         if ( lineNum < marks_.size() )
303ced968a9SNicolas Bonnefon             line = marks_.getLineMarkedByIndex( lineNum );
304bb02e0acSNicolas Bonnefon         else
305bb02e0acSNicolas Bonnefon             LOG(logERROR) << "Index too big in LogFilteredData: " << lineNum;
306bb02e0acSNicolas Bonnefon     }
307bb02e0acSNicolas Bonnefon     else {
308bb02e0acSNicolas Bonnefon         // Regenerate the cache if needed
309bb02e0acSNicolas Bonnefon         if ( filteredItemsCacheDirty_ )
310bb02e0acSNicolas Bonnefon             regenerateFilteredItemsCache();
311bb02e0acSNicolas Bonnefon 
312bb02e0acSNicolas Bonnefon         if ( lineNum < filteredItemsCache_.size() )
313bb02e0acSNicolas Bonnefon             line = filteredItemsCache_[ lineNum ].lineNumber();
314bb02e0acSNicolas Bonnefon         else
315bb02e0acSNicolas Bonnefon             LOG(logERROR) << "Index too big in LogFilteredData: " << lineNum;
316bb02e0acSNicolas Bonnefon     }
317bb02e0acSNicolas Bonnefon 
318bb02e0acSNicolas Bonnefon     return line;
319bb02e0acSNicolas Bonnefon }
320bb02e0acSNicolas Bonnefon 
findFilteredLine(LineNumber lineNum) const3213ff6c941SAnton Filimonov LineNumber LogFilteredData::findFilteredLine( LineNumber lineNum ) const
3223ff6c941SAnton Filimonov {
3233ff6c941SAnton Filimonov     LineNumber lineIndex = std::numeric_limits<LineNumber>::max();
3243ff6c941SAnton Filimonov 
3253ff6c941SAnton Filimonov     if ( visibility_ == MatchesOnly ) {
3263ff6c941SAnton Filimonov         lineIndex = lookupLineNumber( matching_lines_.begin(),
3273ff6c941SAnton Filimonov                                       matching_lines_.end(),
3283ff6c941SAnton Filimonov                                       lineNum );
3293ff6c941SAnton Filimonov     }
3303ff6c941SAnton Filimonov     else if ( visibility_ == MarksOnly ) {
3313ff6c941SAnton Filimonov         lineIndex = lookupLineNumber( marks_.begin(),
3323ff6c941SAnton Filimonov                                       marks_.end(),
3333ff6c941SAnton Filimonov                                       lineNum );
3343ff6c941SAnton Filimonov     }
3353ff6c941SAnton Filimonov     else {
3363ff6c941SAnton Filimonov       // Regenerate the cache if needed
3373ff6c941SAnton Filimonov         if ( filteredItemsCacheDirty_ ) {
3383ff6c941SAnton Filimonov             regenerateFilteredItemsCache();
3393ff6c941SAnton Filimonov         }
3403ff6c941SAnton Filimonov 
3413ff6c941SAnton Filimonov         lineIndex = lookupLineNumber( filteredItemsCache_.begin(),
3423ff6c941SAnton Filimonov                                       filteredItemsCache_.end(),
3433ff6c941SAnton Filimonov                                       lineNum );
3443ff6c941SAnton Filimonov     }
3453ff6c941SAnton Filimonov 
3463ff6c941SAnton Filimonov     return lineIndex;
3473ff6c941SAnton Filimonov }
3483ff6c941SAnton Filimonov 
349bb02e0acSNicolas Bonnefon // Implementation of the virtual function.
doGetLineString(qint64 lineNum) const350bb02e0acSNicolas Bonnefon QString LogFilteredData::doGetLineString( qint64 lineNum ) const
351bb02e0acSNicolas Bonnefon {
352bb02e0acSNicolas Bonnefon     qint64 line = findLogDataLine( lineNum );
353bb02e0acSNicolas Bonnefon 
354bb02e0acSNicolas Bonnefon     QString string = sourceLogData_->getLineString( line );
355bb02e0acSNicolas Bonnefon     return string;
356bb02e0acSNicolas Bonnefon }
357bb02e0acSNicolas Bonnefon 
358bb02e0acSNicolas Bonnefon // Implementation of the virtual function.
doGetExpandedLineString(qint64 lineNum) const359bb02e0acSNicolas Bonnefon QString LogFilteredData::doGetExpandedLineString( qint64 lineNum ) const
360bb02e0acSNicolas Bonnefon {
361bb02e0acSNicolas Bonnefon     qint64 line = findLogDataLine( lineNum );
362bb02e0acSNicolas Bonnefon 
363bb02e0acSNicolas Bonnefon     QString string = sourceLogData_->getExpandedLineString( line );
364bb02e0acSNicolas Bonnefon     return string;
365bb02e0acSNicolas Bonnefon }
366bb02e0acSNicolas Bonnefon 
367bb02e0acSNicolas Bonnefon // Implementation of the virtual function.
doGetLines(qint64 first_line,int number) const368bb02e0acSNicolas Bonnefon QStringList LogFilteredData::doGetLines( qint64 first_line, int number ) const
369bb02e0acSNicolas Bonnefon {
370bb02e0acSNicolas Bonnefon     QStringList list;
371bb02e0acSNicolas Bonnefon 
372bb02e0acSNicolas Bonnefon     for ( int i = first_line; i < first_line + number; i++ ) {
373bb02e0acSNicolas Bonnefon         list.append( doGetLineString( i ) );
374bb02e0acSNicolas Bonnefon     }
375bb02e0acSNicolas Bonnefon 
376bb02e0acSNicolas Bonnefon     return list;
377bb02e0acSNicolas Bonnefon }
378bb02e0acSNicolas Bonnefon 
379bb02e0acSNicolas Bonnefon // Implementation of the virtual function.
doGetExpandedLines(qint64 first_line,int number) const380bb02e0acSNicolas Bonnefon QStringList LogFilteredData::doGetExpandedLines( qint64 first_line, int number ) const
381bb02e0acSNicolas Bonnefon {
382bb02e0acSNicolas Bonnefon     QStringList list;
383bb02e0acSNicolas Bonnefon 
384bb02e0acSNicolas Bonnefon     for ( int i = first_line; i < first_line + number; i++ ) {
385bb02e0acSNicolas Bonnefon         list.append( doGetExpandedLineString( i ) );
386bb02e0acSNicolas Bonnefon     }
387bb02e0acSNicolas Bonnefon 
388bb02e0acSNicolas Bonnefon     return list;
389bb02e0acSNicolas Bonnefon }
390bb02e0acSNicolas Bonnefon 
391bb02e0acSNicolas Bonnefon // Implementation of the virtual function.
doGetNbLine() const392bb02e0acSNicolas Bonnefon qint64 LogFilteredData::doGetNbLine() const
393bb02e0acSNicolas Bonnefon {
394bb02e0acSNicolas Bonnefon     qint64 nbLines;
395bb02e0acSNicolas Bonnefon 
396bb02e0acSNicolas Bonnefon     if ( visibility_ == MatchesOnly )
397ced968a9SNicolas Bonnefon         nbLines = matching_lines_.size();
398bb02e0acSNicolas Bonnefon     else if ( visibility_ == MarksOnly )
399ced968a9SNicolas Bonnefon         nbLines = marks_.size();
400bb02e0acSNicolas Bonnefon     else {
401bb02e0acSNicolas Bonnefon         // Regenerate the cache if needed (hopefully most of the time
402bb02e0acSNicolas Bonnefon         // it won't be necessarily)
403bb02e0acSNicolas Bonnefon         if ( filteredItemsCacheDirty_ )
404bb02e0acSNicolas Bonnefon             regenerateFilteredItemsCache();
405bb02e0acSNicolas Bonnefon         nbLines = filteredItemsCache_.size();
406bb02e0acSNicolas Bonnefon     }
407bb02e0acSNicolas Bonnefon 
408bb02e0acSNicolas Bonnefon     return nbLines;
409bb02e0acSNicolas Bonnefon }
410bb02e0acSNicolas Bonnefon 
411bb02e0acSNicolas Bonnefon // Implementation of the virtual function.
doGetMaxLength() const412bb02e0acSNicolas Bonnefon int LogFilteredData::doGetMaxLength() const
413bb02e0acSNicolas Bonnefon {
414bb02e0acSNicolas Bonnefon     int max_length;
415bb02e0acSNicolas Bonnefon 
416bb02e0acSNicolas Bonnefon     if ( visibility_ == MatchesOnly )
417bb02e0acSNicolas Bonnefon         max_length = maxLength_;
418bb02e0acSNicolas Bonnefon     else if ( visibility_ == MarksOnly )
419bb02e0acSNicolas Bonnefon         max_length = maxLengthMarks_;
420bb02e0acSNicolas Bonnefon     else
421bb02e0acSNicolas Bonnefon         max_length = qMax( maxLength_, maxLengthMarks_ );
422bb02e0acSNicolas Bonnefon 
423bb02e0acSNicolas Bonnefon     return max_length;
424bb02e0acSNicolas Bonnefon }
425bb02e0acSNicolas Bonnefon 
426bb02e0acSNicolas Bonnefon // Implementation of the virtual function.
doGetLineLength(qint64 lineNum) const427bb02e0acSNicolas Bonnefon int LogFilteredData::doGetLineLength( qint64 lineNum ) const
428bb02e0acSNicolas Bonnefon {
429bb02e0acSNicolas Bonnefon     qint64 line = findLogDataLine( lineNum );
430bb02e0acSNicolas Bonnefon     return sourceLogData_->getExpandedLineString( line ).length();
431bb02e0acSNicolas Bonnefon }
432bb02e0acSNicolas Bonnefon 
doSetDisplayEncoding(Encoding encoding)433209000a6SNicolas Bonnefon void LogFilteredData::doSetDisplayEncoding( Encoding encoding )
4345fa25391SNicolas Bonnefon {
435209000a6SNicolas Bonnefon     LOG(logDEBUG) << "AbstractLogData::setDisplayEncoding: " << static_cast<int>( encoding );
4365fa25391SNicolas Bonnefon }
4375fa25391SNicolas Bonnefon 
doSetMultibyteEncodingOffsets(int,int)438481c483cSSergei Dyshel void LogFilteredData::doSetMultibyteEncodingOffsets( int, int )
4394a4a124eSNicolas Bonnefon {
4404a4a124eSNicolas Bonnefon }
4414a4a124eSNicolas Bonnefon 
442bb02e0acSNicolas Bonnefon // TODO: We might be a bit smarter and not regenerate the whole thing when
443bb02e0acSNicolas Bonnefon // e.g. stuff is added at the end of the search.
regenerateFilteredItemsCache() const444bb02e0acSNicolas Bonnefon void LogFilteredData::regenerateFilteredItemsCache() const
445bb02e0acSNicolas Bonnefon {
446bb02e0acSNicolas Bonnefon     LOG(logDEBUG) << "regenerateFilteredItemsCache";
447bb02e0acSNicolas Bonnefon 
448bb02e0acSNicolas Bonnefon     filteredItemsCache_.clear();
449ced968a9SNicolas Bonnefon     filteredItemsCache_.reserve( matching_lines_.size() + marks_.size() );
450bb02e0acSNicolas Bonnefon     // (it's an overestimate but probably not by much so it's fine)
451bb02e0acSNicolas Bonnefon 
452ced968a9SNicolas Bonnefon     auto i = matching_lines_.cbegin();
453ced968a9SNicolas Bonnefon     Marks::const_iterator j = marks_.begin();
454bb02e0acSNicolas Bonnefon 
455ced968a9SNicolas Bonnefon     while ( ( i != matching_lines_.cend() ) || ( j != marks_.end() ) ) {
456bb02e0acSNicolas Bonnefon         qint64 next_mark =
457ced968a9SNicolas Bonnefon             ( j != marks_.end() ) ? j->lineNumber() : std::numeric_limits<qint64>::max();
458bb02e0acSNicolas Bonnefon         qint64 next_match =
459ced968a9SNicolas Bonnefon             ( i != matching_lines_.cend() ) ? i->lineNumber() : std::numeric_limits<qint64>::max();
460bb02e0acSNicolas Bonnefon         // We choose a Mark over a Match if a line is both, just an arbitrary choice really.
461bb02e0acSNicolas Bonnefon         if ( next_mark <= next_match ) {
462bb02e0acSNicolas Bonnefon             // LOG(logDEBUG) << "Add mark at " << next_mark;
463ced968a9SNicolas Bonnefon             filteredItemsCache_.push_back( FilteredItem( next_mark, Mark ) );
464ced968a9SNicolas Bonnefon             if ( j != marks_.end() )
465bb02e0acSNicolas Bonnefon                 ++j;
466ced968a9SNicolas Bonnefon             if ( ( next_mark == next_match ) && ( i != matching_lines_.cend() ) )
467bb02e0acSNicolas Bonnefon                 ++i;  // Case when it's both match and mark.
468bb02e0acSNicolas Bonnefon         }
469bb02e0acSNicolas Bonnefon         else {
470bb02e0acSNicolas Bonnefon             // LOG(logDEBUG) << "Add match at " << next_match;
471ced968a9SNicolas Bonnefon             filteredItemsCache_.push_back( FilteredItem( next_match, Match ) );
472ced968a9SNicolas Bonnefon             if ( i != matching_lines_.cend() )
473bb02e0acSNicolas Bonnefon                 ++i;
474bb02e0acSNicolas Bonnefon         }
475bb02e0acSNicolas Bonnefon     }
476bb02e0acSNicolas Bonnefon 
477bb02e0acSNicolas Bonnefon     filteredItemsCacheDirty_ = false;
478bb02e0acSNicolas Bonnefon 
479bb02e0acSNicolas Bonnefon     LOG(logDEBUG) << "finished regenerateFilteredItemsCache";
480bb02e0acSNicolas Bonnefon }
481