Use a summaries index file instead

This commit is contained in:
Mark Watkins 2014-09-06 00:46:42 +10:00
parent ea96303cc1
commit 41f719fce2
4 changed files with 159 additions and 100 deletions

View File

@ -14,6 +14,9 @@
#include <QThreadPool> #include <QThreadPool>
#include <QFile> #include <QFile>
#include <QDataStream> #include <QDataStream>
#include <QDomDocument>
#include <QDomElement>
#include <QDialog> #include <QDialog>
#include <QHBoxLayout> #include <QHBoxLayout>
@ -468,6 +471,10 @@ const QString Machine::getDataPath()
{ {
return p_profile->Get("{" + STR_GEN_DataFolder + "}/" + info.loadername + "_" + (info.serial.isEmpty() ? hexid() : info.serial)) + "/"; return p_profile->Get("{" + STR_GEN_DataFolder + "}/" + info.loadername + "_" + (info.serial.isEmpty() ? hexid() : info.serial)) + "/";
} }
const QString Machine::getSummariesPath()
{
return getDataPath() + "Summaries/";
}
const QString Machine::getEventsPath() const QString Machine::getEventsPath()
{ {
return getDataPath() + "Events/"; return getDataPath() + "Events/";
@ -501,94 +508,111 @@ bool Machine::Load()
QProgressBar * progress = popup->progress; QProgressBar * progress = popup->progress;
if (!LoadSummary()) { if (!LoadSummary()) {
// No XML index file, so assume upgrading, or it simply just got screwed up or deleted...
QTime time; QTime time;
time.start(); time.start();
dir.setFilter(QDir::Files | QDir::Hidden | QDir::NoSymLinks); dir.setFilter(QDir::Files | QDir::Hidden | QDir::NoSymLinks);
dir.setSorting(QDir::Name);
QFileInfoList list = dir.entryInfoList(); ///////////////////////////////////////////////////////////////////////
// First move any old files to correct locations
///////////////////////////////////////////////////////////////////////
QString summarypath = getSummariesPath();
QString eventpath = getEventsPath();
typedef QVector<QString> StringList; if (!dir.exists(summarypath)) dir.mkpath(summarypath);
QMap<SessionID, StringList> sessfiles;
QMap<SessionID, StringList>::iterator s;
QString fullpath, ext_s, sesstr; QStringList filters;
int ext; filters << "*.000";
SessionID sessid; dir.setNameFilters(filters);
bool ok; QStringList filelist = dir.entryList();
int size = filelist.size();
if (progress) {
progress->setMinimum(0);
for (int i = 0; i < list.size(); i++) { progress->setMaximum(0);
QFileInfo fi = list.at(i); progress->setValue(0);
fullpath = fi.canonicalFilePath(); QApplication::processEvents();
ext_s = fi.fileName().section(".", -1);
ext = ext_s.toInt(&ok, 10);
if (!ok) { continue; }
sesstr = fi.fileName().section(".", 0, -2);
sessid = sesstr.toLong(&ok, 16);
if (!ok) { continue; }
if (sessfiles[sessid].capacity() == 0) { sessfiles[sessid].resize(3); }
sessfiles[sessid][ext] = fi.canonicalFilePath();
} }
int size = sessfiles.size(); for (int i=0; i < size; i++) {
int cnt = 0; QString filename = filelist.at(i);
QFile::copy(path+filename, summarypath+filename);
QFile::remove(path+filename);
}
// Copy old Event files to folder
filters.clear();
filters << "*.001";
dir.setNameFilters(filters);
filelist = dir.entryList();
size = filelist.size();
if (size > 0) {
if (!dir.exists(eventpath)) dir.mkpath(eventpath);
for (int i=0; i< filelist.size(); i++) {
if ((i % 50) == 0) { // This is slow.. :-/
if (progress) { progress->setValue((float(i) / float(size) * 100.0)); }
bool haveevents = false; QApplication::processEvents();
for (s = sessfiles.begin(); s != sessfiles.end(); s++) { }
if (!s.value()[1].isEmpty()) {
haveevents = true; QString filename = filelist.at(i);
break; QFile::copy(path+filename, eventpath+filename);
QFile::remove(path+filename);
} }
} }
QString eventpath = getEventsPath(); ///////////////////////////////////////////////////////////////////////
// Now read summary files from correct location and load them
///////////////////////////////////////////////////////////////////////
dir.setPath(summarypath);
filters.clear();
filters << "*.000";
dir.setNameFilters(filters);
filelist = dir.entryList();
size = filelist.size();
if (haveevents) { if (progress) {
QDir dir; progress->setMinimum(0);
dir.mkpath(eventpath); progress->setMaximum(size);
progress->setValue(0);
QApplication::processEvents();
} }
for (s = sessfiles.begin(); s != sessfiles.end(); s++) { QString sesstr;
if ((++cnt % 50) == 0) { // This is slow.. :-/ SessionID sessid;
if (progress) { progress->setValue((float(cnt) / float(size) * 100.0)); } bool ok;
for (int i=0; i < size; i++) {
if ((i % 50) == 0) { // This is slow.. :-/
if (progress) { progress->setValue(i); }
QApplication::processEvents(); QApplication::processEvents();
} }
Session *sess = new Session(this, s.key()); QString filename = filelist.at(i);
sesstr = filename.section(".", 0, -2);
sessid = sesstr.toLong(&ok, 16);
if (haveevents && !s.value()[1].isEmpty()) { if (!ok) { continue; }
QFile::copy(s.value()[1], eventpath+s.value()[1].section("/",-1));
QFile::remove(s.value()[1]);
}
if (sess->LoadSummary(s.value()[0])) { QString str = summarypath+filename;
Session *sess = new Session(this, sessid);
if (sess->LoadSummary(str)) {
AddSession(sess); AddSession(sess);
} else { } else {
qWarning() << "Error unpacking summary data"; qWarning() << "Error loading summary file" << filename;
delete sess; delete sess;
} }
} }
if (hasModifiedSessions()) { SaveSummary();
SaveSummary();
for (s = sessfiles.begin(); s != sessfiles.end(); s++) {
QString summary = s.value()[0];
QFile file(summary);
file.remove();
}
}
qDebug() << "Loaded" << info.model << "data in" << time.elapsed() << "ms"; qDebug() << "Loaded" << info.model << "data in" << time.elapsed() << "ms";
if (progress) { progress->setValue(size); }
} else {
if (progress) { progress->setValue(100); }
} }
loadSessionInfo(); loadSessionInfo();
if (progress) { progress->setValue(100); }
QApplication::processEvents(); QApplication::processEvents();
popup->hide(); popup->hide();
delete popup; delete popup;
@ -790,81 +814,117 @@ bool Machine::hasModifiedSessions()
return false; return false;
} }
const QString summaryFileName = "Summaries.dat"; const QString summaryFileName = "Summaries.xml";
bool Machine::LoadSummary() bool Machine::LoadSummary()
{ {
QTime time; QTime time;
time.start(); time.start();
qDebug() << "Loading Summaries"; qDebug() << "Loading Summaries";
QString filename = getDataPath() + summaryFileName; QString filename = getDataPath() + summaryFileName;
QDomDocument doc;
QFile file(filename); QFile file(filename);
qDebug() << "Opening " << filename;
if (!file.exists() || !file.open(QFile::ReadOnly)) { if (!file.open(QIODevice::ReadOnly)) {
qDebug() << "Couldn't open" << filename; qWarning() << "Could not open" << filename;
return false; return false;
} }
QByteArray compressed = file.readAll(); QByteArray data=file.readAll();
file.close();
QTime time2;
time2.start();
QByteArray data = qUncompress(compressed);
qDebug() << "Uncompressed Summary Length" << data.size() << "in" << time2.elapsed() << "ms"; QByteArray uncompressed = qUncompress(data);
QDataStream in(&data, QIODevice::ReadOnly); QString errorMsg;
in.setVersion(QDataStream::Qt_5_0); int errorLine;
in.setByteOrder(QDataStream::LittleEndian);
quint32 mag32; if (!doc.setContent(uncompressed, false, &errorMsg, &errorLine)) {
quint16 ftype; qWarning() << "Invalid XML Content in" << filename;
in >> mag32; qWarning() << "Error line" << errorLine << ":" << errorMsg;
in >> ftype; return false;
int session_count;
in >> session_count;
for (int i=0; i< session_count; ++i) {
Session * sess = new Session(this,0);
in >> *sess;
AddSession(sess);
} }
qDebug() << "Loaded" << info.model << "data in" << time.elapsed() << "ms"; file.close();
QDomElement root = doc.documentElement();
QDomNode node;
bool s_ok;
QString sumpath = getSummariesPath();
QDomNodeList sessionlist = root.childNodes();
int size = sessionlist.size();
for (int s=0; s < size; ++s) {
node = sessionlist.at(s);
QDomElement e = node.toElement();
SessionID sessid = e.attribute("id", "0").toLong(&s_ok);
qint64 first = e.attribute("first", 0).toLongLong();
qint64 last = e.attribute("last", 0).toLongLong();
if (s_ok) {
Session * sess = new Session(this, sessid);
QString filename = sumpath + QString().sprintf("%08lx.000", sessid);
if (sess->LoadSummary(filename)) {
AddSession(sess);
} else {
delete sess;
}
}
}
qDebug() << "Loaded" << info.series << info.model << "data in" << time.elapsed() << "ms";
return true; return true;
} }
const int summaryxml_version=0;
bool Machine::SaveSummary() bool Machine::SaveSummary()
{ {
qDebug() << "Saving Summaries"; qDebug() << "Saving Summaries";
QString filename = getDataPath() + summaryFileName; QString filename = getDataPath() + summaryFileName;
QByteArray data; QDomDocument doc("SleepyHeadSessionIndex");
QDataStream out(&data, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_5_0);
out.setByteOrder(QDataStream::LittleEndian);
out << (quint32)magic; QDomElement root = doc.createElement("sessions");
out << (quint16)filetype_summary; root.setAttribute("version", summaryxml_version);
out << (int)sessionlist.size(); root.setAttribute("profile", p_profile->user->userName());
root.setAttribute("count", sessionlist.size());
root.setAttribute("loader", info.loadername);
root.setAttribute("serial", info.serial);
doc.appendChild(root);
if (!QDir().exists(getSummariesPath()))
QDir().mkpath(getSummariesPath());
QHash<SessionID, Session *>::iterator s; QHash<SessionID, Session *>::iterator s;
for (s = sessionlist.begin(); s != sessionlist.end(); s++) { QHash<SessionID, Session *>::iterator sess_end = sessionlist.end();
for (s = sessionlist.begin(); s != sess_end; ++s) {
QDomElement el = doc.createElement("session");
Session * sess = s.value(); Session * sess = s.value();
out << *sess; el.setAttribute("id", (quint32)sess->session());
el.setAttribute("first", sess->realFirst());
el.setAttribute("last", sess->realLast());
el.setAttribute("enabled", sess->enabled() ? "1" : "0");
el.setAttribute("events", sess->summaryOnly() ? "0" : "1");
root.appendChild(el);
if (sess->IsChanged())
sess->StoreSummary();
} }
QFile file(filename); QFile file(filename);
file.open(QIODevice::WriteOnly); file.open(QIODevice::WriteOnly);
qDebug() << "Uncompressed Summary Length" << data.size(); QByteArray ba = qCompress(doc.toByteArray());
file.write(ba);
QByteArray compressed = qCompress(data);
file.write(compressed);
file.close(); file.close();
return true; return true;
} }

View File

@ -123,6 +123,7 @@ class Machine
const QString getDataPath(); const QString getDataPath();
const QString getEventsPath(); const QString getEventsPath();
const QString getSummariesPath();
const QString getBackupPath(); const QString getBackupPath();
//! \brief Returns the machineID as a lower case hexadecimal string //! \brief Returns the machineID as a lower case hexadecimal string

View File

@ -260,10 +260,7 @@ void Session::LoadSummaryData(QDataStream & in)
bool Session::StoreSummary() bool Session::StoreSummary()
{ {
// don't really want to call this anymore QString filename = s_machine->getSummariesPath() + QString().sprintf("%08lx.000", s_session);
return true;
QString filename = s_machine->getDataPath() + QString().sprintf("%08lx.000", s_session);
QFile file(filename); QFile file(filename);
file.open(QIODevice::WriteOnly); file.open(QIODevice::WriteOnly);

View File

@ -111,6 +111,9 @@ class Session
//! \brief Sets whether or not session is being used. //! \brief Sets whether or not session is being used.
void setEnabled(bool b) { s_enabled = b; } void setEnabled(bool b) { s_enabled = b; }
inline qint64 realFirst() const { return s_first; }
inline qint64 realLast() const { return s_last; }
//! \brief Return the start of this sessions time range (in milliseconds since epoch) //! \brief Return the start of this sessions time range (in milliseconds since epoch)
qint64 first(); qint64 first();
@ -209,8 +212,6 @@ class Session
QList<SessionSlice> m_slices; QList<SessionSlice> m_slices;
const QList<ChannelID> & availableChannels() { return m_availableChannels; }
//! \brief Generates sum and time data for each distinct value in 'code' events.. //! \brief Generates sum and time data for each distinct value in 'code' events..
void updateCountSummary(ChannelID code); void updateCountSummary(ChannelID code);