+ for file-based recovery write the data files in worker threads
This commit is contained in:
parent
848f9c4d46
commit
e5c3a09502
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue
Block a user