Further improve speed of PipeCapture for non-watched output (#777973)
For large output a lot of time is used copying capturebuf to callerbuf to provide a Glib::ustring copy of the buffer for the update callback. However update callbacks are only used when commands are run to apply operations by FileSystem::execute_command() and their output is incrementally displayed in the UI. Whereas update callbacks are never used when commands are used to query information via Utils::execute_command(). Stop performing interim copying of capturebuf to callerbuf when there are no update callbacks registered as it is unnecessary. Time to read portions of the recorded fsck.fat output via fat16::set_used_sectors() and intermediate copies aren't required: 1 MiB 10 MiB 122 MiB old code : 0.074 sec 1.41 sec 210 sec [3:30] new code : 0.063 sec 0.56 sec 6.57 sec Bug 777973 - Segmentation fault on bad disk
This commit is contained in:
parent
6f49f3049d
commit
25780c611b
|
@ -55,6 +55,7 @@ private:
|
|||
std::string capturebuf; // Captured output as UTF-8 characters
|
||||
size_t line_start; // Index into bytebuf where current line starts
|
||||
Glib::ustring & callerbuf; // Reference to caller supplied buffer
|
||||
bool callerbuf_uptodate; // Has capturebuf changed since last copied to callerbuf?
|
||||
};
|
||||
|
||||
} // namepace GParted
|
||||
|
|
|
@ -37,6 +37,7 @@ PipeCapture::PipeCapture( int fd, Glib::ustring &buffer ) : fill_offset( 0 ),
|
|||
{
|
||||
readbuf = new char[READBUF_SIZE];
|
||||
callerbuf.clear();
|
||||
callerbuf_uptodate = true;
|
||||
// tie fd to string
|
||||
// make channel
|
||||
channel = Glib::IOChannel::create_from_fd( fd );
|
||||
|
@ -95,10 +96,10 @@ bool PipeCapture::OnReadable( Glib::IOCondition condition )
|
|||
// is drained the partial current line, is pasted into capturebuf at the offset
|
||||
// where the last line starts. (Capturebuf stores UTF-8 encoded characters in a
|
||||
// std::string for constant time access to line_start offset). When readbuf
|
||||
// is drained capturebuf is copied into callerbuf and signal_update slot fired.
|
||||
// (Callerbuf stores UTF-8 encoded characters in a Glib::ustring). When EOF is
|
||||
// encountered capturebuf is copied into callerbuf if required and signal_eof slot
|
||||
// fired.
|
||||
// is drained and there are registered update callbacks, capturebuf is copied into
|
||||
// callerbuf and signal_update slot fired. (Callerbuf stores UTF-8 encoded
|
||||
// characters in a Glib::ustring). When EOF is encountered capturebuf is copied
|
||||
// into callerbuf if required and signal_eof slot fired.
|
||||
//
|
||||
// Golden rule:
|
||||
// Use Glib::ustrings as little as possible for large amounts of data!
|
||||
|
@ -187,6 +188,7 @@ bool PipeCapture::OnReadable( Glib::IOCondition condition )
|
|||
capturebuf.resize( line_start );
|
||||
append_unichar_vector_to_utf8( capturebuf, linevec );
|
||||
line_start = capturebuf.size();
|
||||
callerbuf_uptodate = false;
|
||||
|
||||
linevec.clear();
|
||||
cursor = 0;
|
||||
|
@ -213,13 +215,20 @@ bool PipeCapture::OnReadable( Glib::IOCondition condition )
|
|||
}
|
||||
}
|
||||
|
||||
// Paste partial line to capture buffer; copy that to callers buffer; and
|
||||
// fire any update callbacks.
|
||||
// Paste partial line to capture buffer.
|
||||
capturebuf.resize( line_start );
|
||||
append_unichar_vector_to_utf8( capturebuf, linevec );
|
||||
callerbuf_uptodate = false;
|
||||
|
||||
callerbuf = capturebuf;
|
||||
signal_update.emit();
|
||||
if ( ! signal_update.empty() )
|
||||
{
|
||||
// Performance optimisation, especially for large capture buffers:
|
||||
// only copy capture buffer to callers buffer and fire update
|
||||
// callbacks when there are any registered update callbacks.
|
||||
callerbuf = capturebuf;
|
||||
callerbuf_uptodate = true;
|
||||
signal_update.emit();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -228,6 +237,11 @@ bool PipeCapture::OnReadable( Glib::IOCondition condition )
|
|||
std::cerr << "Pipe IOChannel read failed" << std::endl;
|
||||
}
|
||||
|
||||
if ( ! callerbuf_uptodate )
|
||||
{
|
||||
callerbuf = capturebuf;
|
||||
callerbuf_uptodate = true;
|
||||
}
|
||||
// signal completion
|
||||
signal_eof.emit();
|
||||
return false;
|
||||
|
|
Loading…
Reference in New Issue