Skip to content

Commit

Permalink
Optimize filteredItemsCache_ filling
Browse files Browse the repository at this point in the history
by passing in a guess for the index.
  • Loading branch information
gin-ahirsch committed Aug 10, 2018
1 parent e18d691 commit 70538f4
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 20 deletions.
72 changes: 54 additions & 18 deletions src/data/logfiltereddata.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -177,10 +177,10 @@ LogFilteredData::FilteredLineType
void LogFilteredData::addMark( qint64 line, QChar mark )
{
if ( ( line >= 0 ) && ( line < sourceLogData_->getNbLine() ) ) {
marks_.addMark( line, mark );
int index = marks_.addMark( line, mark );
maxLengthMarks_ = qMax( maxLengthMarks_,
sourceLogData_->getLineLength( line ) );
insertIntoFilteredItemsCache( FilteredItem{ static_cast<LineNumber>( line ), Mark } );
insertIntoFilteredItemsCache( index, FilteredItem{ static_cast<LineNumber>( line ), Mark } );
}
else
LOG(logERROR) << "LogFilteredData::addMark\
Expand Down Expand Up @@ -237,15 +237,15 @@ void LogFilteredData::deleteMark( QChar mark )
}

updateMaxLengthMarks( line );
removeFromFilteredItemsCache( FilteredItem{ static_cast<LineNumber>( line ), Mark } );
removeFromFilteredItemsCache( index, FilteredItem{ static_cast<LineNumber>( line ), Mark } );
}

void LogFilteredData::deleteMark( qint64 line )
{
marks_.deleteMark( line );
int index = marks_.deleteMark( line );

updateMaxLengthMarks( line );
removeFromFilteredItemsCache( FilteredItem{ static_cast<LineNumber>( line ), Mark } );
removeFromFilteredItemsCache( index, FilteredItem{ static_cast<LineNumber>( line ), Mark } );
}

void LogFilteredData::updateMaxLengthMarks( qint64 removed_line )
Expand Down Expand Up @@ -300,14 +300,7 @@ void LogFilteredData::handleSearchProgressed( int nbMatches, int progress, qint6

workerThread_.updateSearchResult( &maxLength_, &matching_lines_, &nbLinesProcessed_ );

assert( matching_lines_.size() >= start_index );

filteredItemsCache_.reserve( matching_lines_.size() + marks_.size() );
// (it's an overestimate but probably not by much so it's fine)

for ( auto it = next( begin( matching_lines_ ), start_index ); it != end( matching_lines_ ); ++it ) {
insertIntoFilteredItemsCache( FilteredItem{ it->lineNumber(), Match } );
}
insertMatchesIntoFilteredItemsCache( start_index );

emit searchProgressed( nbMatches, progress, initial_position );
}
Expand Down Expand Up @@ -492,20 +485,21 @@ void LogFilteredData::regenerateFilteredItemsCache() const
LOG(logDEBUG) << "finished regenerateFilteredItemsCache";
}

void LogFilteredData::insertIntoFilteredItemsCache( FilteredItem item )
void LogFilteredData::insertIntoFilteredItemsCache( size_t insert_index, FilteredItem item )
{
using std::begin;
using std::end;
using std::next;

if ( visibility_ != MarksAndMatches ) {
// this is invalidated and will be regenerated when we need it
filteredItemsCache_.clear();
LOG(logDEBUG) << "cache is invalidated";
return;
}

// Search for the corresponding index.
auto found = std::lower_bound( begin( filteredItemsCache_ ), end( filteredItemsCache_ ), item );
// We can start the search from insert_index, since lineNumber >= index is always true.
auto found = std::lower_bound( next( begin( filteredItemsCache_ ), insert_index ), end( filteredItemsCache_ ), item );
if ( found == end( filteredItemsCache_ ) || found->lineNumber() > item.lineNumber() ) {
filteredItemsCache_.insert( found, item );
} else {
Expand All @@ -514,11 +508,52 @@ void LogFilteredData::insertIntoFilteredItemsCache( FilteredItem item )
}
}

void LogFilteredData::removeFromFilteredItemsCache( FilteredItem item )
void LogFilteredData::insertIntoFilteredItemsCache( FilteredItem item )
{
insertIntoFilteredItemsCache( 0, item );
}

void LogFilteredData::insertMatchesIntoFilteredItemsCache( size_t start_index )
{
using std::begin;
using std::end;
using std::next;

assert( start_index <= matching_lines_.size() );

if ( visibility_ != MarksAndMatches ) {
// this is invalidated and will be regenerated when we need it
filteredItemsCache_.clear();
LOG(logDEBUG) << "cache is invalidated";
return;
}

assert( start_index <= filteredItemsCache_.size() );

filteredItemsCache_.reserve( matching_lines_.size() + marks_.size() );
// (it's an overestimate but probably not by much so it's fine)

// Search for the corresponding index.
// We can start the search from insert_index, since lineNumber >= index is always true.
auto filteredIt = next( begin( filteredItemsCache_ ), start_index );
for ( auto matchesIt = next( begin( matching_lines_ ), start_index ); matchesIt != end( matching_lines_ ); ++matchesIt ) {
FilteredItem item{ matchesIt->lineNumber(), Match };
filteredIt = std::lower_bound( filteredIt, end( filteredItemsCache_ ), item );
if ( filteredIt == end( filteredItemsCache_ ) || filteredIt->lineNumber() > item.lineNumber() ) {
filteredIt = filteredItemsCache_.insert( filteredIt, item );
} else {
assert( filteredIt->lineNumber() == matchesIt->lineNumber() );
filteredIt->add( item.type() );
}
}
}

void LogFilteredData::removeFromFilteredItemsCache( size_t remove_index, FilteredItem item )
{
using std::begin;
using std::distance;
using std::end;
using std::next;

if ( visibility_ != MarksAndMatches ) {
// this is invalidated and will be regenerated when we need it
Expand All @@ -528,7 +563,8 @@ void LogFilteredData::removeFromFilteredItemsCache( FilteredItem item )
}

// Search for the corresponding index.
auto found = std::equal_range( begin( filteredItemsCache_ ), end( filteredItemsCache_ ), item );
// We can start the search from remove_index, since lineNumber >= index is always true.
auto found = std::equal_range( next( begin( filteredItemsCache_ ), remove_index ), end( filteredItemsCache_ ), item );
if( found.first == end( filteredItemsCache_ ) ) {
LOG(logERROR) << "Attempt to remove line " << item.lineNumber() << " from filteredItemsCache_ failed, since it was not found";
return;
Expand Down
8 changes: 8 additions & 0 deletions src/data/logfiltereddata.h
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,15 @@ class LogFilteredData : public AbstractLogData {
LineNumber findFilteredLine( LineNumber lineNum ) const;

void regenerateFilteredItemsCache() const;
// start_index can be passed in as an optimization when finding the item.
// It refers to the index of the singular arrays (Marks or SearchResultArray) where the item was inserted.
void insertIntoFilteredItemsCache( size_t start_index, FilteredItem item );
void insertIntoFilteredItemsCache( FilteredItem item );
// Insert entries from matching_lines_ into filteredItemsCache_ starting by start_index.
void insertMatchesIntoFilteredItemsCache( size_t start_index );
// remove_index can be passed in as an optimization when finding the item.
// It refers to the index of the singular arrays (Marks or SearchResultArray) where the item was removed.
void removeFromFilteredItemsCache( size_t remove_index, FilteredItem item );
void removeFromFilteredItemsCache( FilteredItem item );
void removeAllFromFilteredItemsCache( FilteredLineType type );

Expand Down
4 changes: 3 additions & 1 deletion src/marks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ Marks::Marks() : marks_()
{
}

void Marks::addMark( qint64 line, QChar mark )
int Marks::addMark( qint64 line, QChar mark )
{
// Look for the index immediately before
int index;
Expand All @@ -50,6 +50,8 @@ void Marks::addMark( qint64 line, QChar mark )

// 'mark' is not used yet
mark = mark;

return index;
}

qint64 Marks::getMark( QChar mark ) const
Expand Down
4 changes: 3 additions & 1 deletion src/marks.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,9 @@ class Marks {
// Add a mark at the given line, optionally identified by the given char
// If a mark for this char already exist, the previous one is replaced.
// It will happily add marks anywhere, even at stupid indexes.
void addMark( qint64 line, QChar mark = QChar() );
// Returns the index at which the mark was inserted,
// such that getLineMarkedByIndex( addMark( line ) ) == line.
int addMark( qint64 line, QChar mark = QChar() );
// Get the (unique) mark identified by the passed char.
qint64 getMark( QChar mark ) const;
// Returns wheither the passed line has a mark on it.
Expand Down

0 comments on commit 70538f4

Please sign in to comment.