+ for file-based recovery write the data files in worker threads

This commit is contained in:
wmayer 2015-09-19 13:12:59 +02:00
parent 848f9c4d46
commit e5c3a09502
4 changed files with 97 additions and 4 deletions

View File

@ -113,12 +113,22 @@ void Writer::setMode(const std::string& mode)
Modes.insert(mode);
}
void Writer::setModes(const std::set<std::string>& modes)
{
Modes = modes;
}
bool Writer::getMode(const std::string& mode) const
{
std::set<std::string>::const_iterator it = Modes.find(mode);
return (it != Modes.end());
}
std::set<std::string> Writer::getModes() const
{
return Modes;
}
void Writer::clearMode(const std::string& mode)
{
std::set<std::string>::iterator it = Modes.find(mode);
@ -126,6 +136,11 @@ void Writer::clearMode(const std::string& mode)
Modes.erase(it);
}
void Writer::clearModes()
{
Modes.clear();
}
std::string Writer::addFile(const char* Name,const Base::Persistence *Object)
{
// always check isForceXML() before requesting a file!
@ -261,7 +276,7 @@ FileWriter::~FileWriter()
void FileWriter::putNextEntry(const char* file)
{
std::string fileName = DirName + "/" + file;
this->FileStream.open(fileName.c_str(), std::ios::out);
this->FileStream.open(fileName.c_str(), std::ios::out | std::ios::binary);
}
bool FileWriter::shouldWrite(const std::string& , const Base::Persistence *) const

View File

@ -83,10 +83,16 @@ public:
const std::vector<std::string>& getFilenames() const;
/// Set mode
void setMode(const std::string& mode);
/// Set modes
void setModes(const std::set<std::string>& modes);
/// Get mode
bool getMode(const std::string& mode) const;
/// Get modes
std::set<std::string> getModes() const;
/// Clear mode
void clearMode(const std::string& mode);
/// Clear modes
void clearModes();
//@}
/** @name pretty formating for XML */
@ -187,7 +193,7 @@ public:
*/
virtual bool shouldWrite(const std::string& name, const Base::Persistence *Object) const;
private:
protected:
std::string DirName;
std::ofstream FileStream;
};

View File

@ -26,7 +26,9 @@
#ifndef _PreComp_
# include <QApplication>
# include <QFile>
# include <QRunnable>
# include <QTextStream>
# include <QThreadPool>
# include <boost/bind.hpp>
# include <sstream>
#endif
@ -52,7 +54,7 @@ using namespace Gui;
AutoSaver* AutoSaver::self = 0;
AutoSaver::AutoSaver(QObject* parent)
: QObject(parent), timeout(900000), compressed(false)
: QObject(parent), timeout(900000), compressed(true)
{
App::GetApplication().signalNewDocument.connect(boost::bind(&AutoSaver::slotCreateDocument, this, _1));
App::GetApplication().signalDeleteDocument.connect(boost::bind(&AutoSaver::slotDeleteDocument, this, _1));
@ -170,7 +172,8 @@ void AutoSaver::saveDocument(const std::string& name, AutoSaveProperty& saver)
// write additional files
writer.writeFiles();
}
else {
// only create the file if something has changed
else if (!saver.touched.empty()) {
std::string fn = doc->TransientDir.getValue();
fn += "/fc_recovery_file.fcstd";
Base::FileInfo tmp(fn);
@ -297,5 +300,73 @@ bool RecoveryWriter::shouldWrite(const std::string& name, const Base::Persistenc
return (jt != saver.touched.end());
}
namespace Gui {
class RecoveryRunnable : public QRunnable
{
public:
RecoveryRunnable(const std::set<std::string>& modes, const char* dir, const char* file, const App::Property* p)
: prop(p->Copy())
, writer(dir)
{
writer.setModes(modes);
writer.putNextEntry(file);
}
virtual ~RecoveryRunnable()
{
delete prop;
}
virtual void run()
{
prop->SaveDocFile(writer);
}
private:
App::Property* prop;
Base::FileWriter writer;
};
}
void RecoveryWriter::writeFiles(void)
{
#if 0
FileWriter::writeFiles();
#else
// use a while loop because it is possible that while
// processing the files new ones can be added
size_t index = 0;
this->FileStream.close();
while (index < FileList.size()) {
FileEntry entry = FileList.begin()[index];
if (shouldWrite(entry.FileName, entry.Object)) {
std::string filePath = entry.FileName;
std::string::size_type pos = 0;
while ((pos = filePath.find("/", pos)) != std::string::npos) {
std::string dirName = DirName + "/" + filePath.substr(0, pos);
pos++;
Base::FileInfo fi(dirName);
fi.createDirectory();
}
// For properties a copy can be created and then this can be written to disk in a thread
if (entry.Object->isDerivedFrom(App::Property::getClassTypeId())) {
const App::Property* prop = static_cast<const App::Property*>(entry.Object);
QThreadPool::globalInstance()->start(new RecoveryRunnable(getModes(), DirName.c_str(), entry.FileName.c_str(), prop));
}
else {
std::string fileName = DirName + "/" + entry.FileName;
this->FileStream.open(fileName.c_str(), std::ios::out | std::ios::binary);
entry.Object->SaveDocFile(*this);
this->FileStream.close();
}
}
index++;
}
#endif
}
#include "moc_AutoSaver.cpp"

View File

@ -106,6 +106,7 @@ public:
always returns true.
*/
virtual bool shouldWrite(const std::string&, const Base::Persistence *) const;
virtual void writeFiles(void);
private:
AutoSaveProperty& saver;