Skip to content

Commit

Permalink
+ for file-based recovery write the data files in worker threads
Browse files Browse the repository at this point in the history
  • Loading branch information
wwmayer committed Sep 19, 2015
1 parent 848f9c4 commit e5c3a09
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 4 deletions.
17 changes: 16 additions & 1 deletion src/Base/Writer.cpp
Expand Up @@ -113,19 +113,34 @@ 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);
if (it != Modes.end())
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!
Expand Down Expand Up @@ -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
Expand Down
8 changes: 7 additions & 1 deletion src/Base/Writer.h
Expand Up @@ -83,10 +83,16 @@ class BaseExport Writer
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 */
Expand Down Expand Up @@ -187,7 +193,7 @@ class BaseExport FileWriter : public Writer
*/
virtual bool shouldWrite(const std::string& name, const Base::Persistence *Object) const;

private:
protected:
std::string DirName;
std::ofstream FileStream;
};
Expand Down
75 changes: 73 additions & 2 deletions src/Gui/AutoSaver.cpp
Expand Up @@ -26,7 +26,9 @@
#ifndef _PreComp_
# include <QApplication>
# include <QFile>
# include <QRunnable>
# include <QTextStream>
# include <QThreadPool>
# include <boost/bind.hpp>
# include <sstream>
#endif
Expand All @@ -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));
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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"
1 change: 1 addition & 0 deletions src/Gui/AutoSaver.h
Expand Up @@ -106,6 +106,7 @@ class RecoveryWriter : public Base::FileWriter
always returns true.
*/
virtual bool shouldWrite(const std::string&, const Base::Persistence *) const;
virtual void writeFiles(void);

private:
AutoSaveProperty& saver;
Expand Down

0 comments on commit e5c3a09

Please sign in to comment.