FS: Fix performance on high latency systems

fseek() in File::append() was invalidating the file buffer for each call
to append().  Better handling improves "import" performance test by 9%,
45% in "commit", on a system with a spinning disk.

This performance problem affects all operations where
{pending,completed}.data are rewritten.  During normal operation a
garbage collection can be enough to trigger it.  On storage with high
latency, e.g. networked, this previously took 20 seconds and more.
This commit is contained in:
Wilhelm Schuermann 2015-11-11 08:40:07 +01:00
parent e6f142be17
commit ad81810fd3
3 changed files with 20 additions and 7 deletions

View file

@ -505,7 +505,19 @@ void File::append (const std::vector <std::string>& lines)
{
fseek (_fh, 0, SEEK_END);
for (auto& line : lines)
fputs ((line + "\n").c_str (), _fh);
fputs (line.c_str (), _fh);
}
}
////////////////////////////////////////////////////////////////////////////////
void File::write_raw (const std::string& line)
{
if (!_fh)
open ();
if (_fh)
{
fputs (line.c_str (), _fh);
}
}

View file

@ -91,6 +91,7 @@ public:
void append (const std::string&);
void append (const std::vector <std::string>&);
void write_raw (const std::string&);
void truncate ();

View file

@ -257,14 +257,14 @@ void TF2::commit ()
_file.lock ();
// Write out all the added tasks.
_file.append (std::string("")); // Seek to end of file
for (auto& task : _added_tasks)
_file.append (task.composeF4 () + "\n");
_file.write_raw (task.composeF4 () + "\n");
_added_tasks.clear ();
// Write out all the added lines.
for (auto& line : _added_lines)
_file.append (line);
_file.append (_added_lines);
_added_lines.clear ();
_file.close ();
@ -282,12 +282,12 @@ void TF2::commit ()
_file.truncate ();
// Only write out _tasks, because any deltas have already been applied.
_file.append (std::string("")); // Seek to end of file
for (auto& task : _tasks)
_file.append (task.composeF4 () + "\n");
_file.write_raw (task.composeF4 () + "\n");
// Write out all the added lines.
for (auto& line : _added_lines)
_file.append (line);
_file.append (_added_lines);
_added_lines.clear ();
_file.close ();