Multithreaded import (save) feature.. View Menu option turns it on/off

This commit is contained in:
Mark Watkins 2011-09-09 04:38:07 +10:00
parent bc0f386826
commit ddf2464c0c
13 changed files with 232 additions and 32 deletions

View File

@ -346,8 +346,79 @@ void AHIChart::SetDay(Day * day)
if (total>m_maxy) m_maxy=total;
}
}
//m_maxy=ceil(m_maxy);
//m_miny=floor(m_miny);
m_miny=0;
// m_minx=qint64(QDateTime(m_profile->FirstDay(),QTime(0,0,0),Qt::UTC).toTime_t())*1000L;
m_maxx=qint64(QDateTime(m_profile->LastDay().addDays(1),QTime(0,0,0),Qt::UTC).toTime_t())*1000L;
m_empty=m_values.size()==0;
}
AvgChart::AvgChart(Profile *profile)
:gBarChart()
{
m_label="Avg";
m_profile=profile;
}
void AvgChart::SetDay(Day * day)
{
if (!m_profile) {
qWarning() << "Forgot to set profile for gBarChart dummy!";
m_day=NULL;
return;
}
Layer::SetDay(day);
m_values.clear();
m_miny=9999999;
m_maxy=-9999999;
m_minx=0;
m_maxx=0;
int dn;
EventDataType tmp,total;
ChannelID code;
m_fday=0;
qint64 tt;
for (QMap<QDate,QVector<Day *> >::iterator d=m_profile->daylist.begin();d!=m_profile->daylist.end();d++) {
tt=QDateTime(d.key(),QTime(0,0,0),Qt::UTC).toTime_t();
//tt=QDateTime(d.key(),QTime(12,0,0)).toTime_t();
dn=tt/86400;
tt*=1000L;
if (!m_minx || tt<m_minx) m_minx=tt;
if (!m_maxx || tt>m_maxx) m_maxx=tt;
total=0;
bool fnd=false;
for (int j=0;j<m_codes.size();j++) {
code=m_codes[j];
for (int i=0;i<d.value().size();i++) {
Day *day=d.value()[i];
if (day->channelExists(code)) { // too many lookups happening here.. stop the crap..
tmp=day->wavg(code);
if (tmp>0) {
fnd=true;
total+=tmp;
m_values[dn][j+1]=tmp;
break;
}
}
}
}
if (fnd) {
if (!m_fday) m_fday=dn;
m_values[dn][0]=total;
if (total<m_miny) m_miny=total;
if (total>m_maxy) m_maxy=total;
}
}
m_miny=0;
// m_minx=qint64(QDateTime(m_profile->FirstDay(),QTime(0,0,0),Qt::UTC).toTime_t())*1000L;

View File

@ -61,4 +61,11 @@ public:
virtual void SetDay(Day * day);
};
class AvgChart:public gBarChart
{
public:
AvgChart(Profile *profile);
virtual void SetDay(Day * day);
};
#endif // GBARCHART_H

View File

@ -1888,6 +1888,7 @@ void gGraphView::setDay(Day * day)
for (int i=0;i<m_graphs.size();i++) {
m_graphs[i]->setDay(day);
}
ResetBounds();
}
void gGraphView::TimedRefresh()
{

View File

@ -186,7 +186,7 @@ EventDataType Day::wavg(ChannelID code)
qint64 d;
for (QVector<Session *>::iterator s=sessions.begin();s!=sessions.end();s++) {
Session & sess=*(*s);
if (sess.eventlist.contains(code)) {
if (sess.m_wavg.contains(code)) {
d=sess.last(code)-sess.first(code);
s0=double(d)/1000.0;
if (s0>0) {

View File

@ -320,7 +320,7 @@ int PRS1Loader::OpenMachine(Machine *m,QString path,Profile *profile)
CPAP_Obstructive, CPAP_Hypopnea, CPAP_ClearAirway, CPAP_RERA, CPAP_FlowLimit, CPAP_VSnore,
CPAP_CSR, PRS1_VSnore2
};
for (unsigned i=0;i<sizeof(e)/sizeof(ChannelID);i++) {
/*for (unsigned i=0;i<sizeof(e)/sizeof(ChannelID);i++) {
sess->count(e[i]);
sess->max(e[i]);
sess->min(e[i]);
@ -328,7 +328,7 @@ int PRS1Loader::OpenMachine(Machine *m,QString path,Profile *profile)
sess->p90(e[i]);
sess->cph(e[i]);
sess->sph(e[i]);
}
}*/
sess->setCph(CPAP_AHI,sess->cph(CPAP_Obstructive)+sess->cph(CPAP_Hypopnea)+sess->cph(CPAP_ClearAirway));
sess->setSph(CPAP_AHI,sess->sph(CPAP_Obstructive)+sess->sph(CPAP_Hypopnea)+sess->sph(CPAP_ClearAirway));
@ -340,11 +340,11 @@ int PRS1Loader::OpenMachine(Machine *m,QString path,Profile *profile)
};
for (unsigned i=0;i<sizeof(a)/sizeof(ChannelID);i++) {
if (sess->eventlist.contains(a[i])) {
sess->min(a[i]);
/*sess->min(a[i]);
sess->max(a[i]);
sess->avg(a[i]);
sess->wavg(a[i]);
sess->p90(a[i]);
sess->p90(a[i]); */
sess->cph(a[i]);
}
}

View File

@ -571,16 +571,92 @@ bool Machine::Save()
QHash<SessionID,Session *>::iterator s;
m_savelist.clear();
for (s=sessionlist.begin(); s!=sessionlist.end(); s++) {
cnt++;
if (qprogress) qprogress->setValue(66.0+(float(cnt)/float(size)*33.0));
if ((*s)->IsChanged()) (*s)->Store(path);
(*s)->TrashEvents();
QApplication::processEvents();
if ((*s)->IsChanged()) {
m_savelist.push_back(*s);
//(*s)->UpdateSummaries();
//(*s)->Store(path);
//(*s)->TrashEvents();
}
}
savelistCnt=0;
savelistSize=m_savelist.size();
if (!pref["EnableMultithreading"].toBool()) {
for (int i=0;i<savelistSize;i++) {
qprogress->setValue(66.0+(float(savelistCnt)/float(savelistSize)*33.0));
QApplication::processEvents();
Session *s=m_savelist.at(i);
s->UpdateSummaries();
s->Store(path);
s->TrashEvents();
savelistCnt++;
}
return true;
}
int threads=QThread::idealThreadCount();
savelistSem=new QSemaphore(threads);
savelistSem->acquire(threads);
QVector<SaveThread*>thread;
for (int i=0;i<threads;i++) {
thread.push_back(new SaveThread(this,path));
QObject::connect(thread[i],SIGNAL(UpdateProgress(int)),qprogress,SLOT(setValue(int)));
thread[i]->start();
}
while (!savelistSem->tryAcquire(threads,250)) {
//qDebug() << savelistSem->available();
if (qprogress) {
// qprogress->setValue(66.0+(float(savelistCnt)/float(savelistSize)*33.0));
QApplication::processEvents();
}
}
for (int i=0;i<threads;i++) {
while (thread[i]->isRunning()) {
usleep(250);
QApplication::processEvents();
}
delete thread[i];
}
delete savelistSem;
return true;
}
/*SaveThread::SaveThread(Machine *m,QString p)
{
machine=m;
path=p;
} */
void SaveThread::run()
{
while (Session *sess=machine->popSaveList()) {
int i=66.0+(float(machine->savelistCnt)/float(machine->savelistSize)*33.0);
emit UpdateProgress(i);
sess->UpdateSummaries();
sess->Store(path);
sess->TrashEvents();
}
machine->savelistSem->release(1);
}
Session *Machine::popSaveList()
{
Session *sess=NULL;
savelistMutex.lock();
if (m_savelist.size()>0) {
sess=m_savelist.at(0);
m_savelist.pop_front();
savelistCnt++;
}
savelistMutex.unlock();
return sess;
}
//////////////////////////////////////////////////////////////////////////////////////////
// CPAP implmementation
//////////////////////////////////////////////////////////////////////////////////////////

View File

@ -10,6 +10,9 @@
#include <QString>
#include <QVariant>
#include <QDateTime>
#include <QThread>
#include <QMutex>
#include <QSemaphore>
#include <QHash>
#include <QVector>
@ -28,6 +31,18 @@ class Session;
class Profile;
class Machine;
class SaveThread:public QThread
{
Q_OBJECT
public:
SaveThread(Machine *m,QString p) { machine=m; path=p; }
virtual void run();
protected:
Machine *machine;
QString path;
signals:
void UpdateProgress(int i);
};
class Machine
{
@ -45,6 +60,12 @@ public:
QHash<SessionID,Session *> sessionlist;
QHash<QString,QString> properties;
Session *popSaveList();
QList<Session *> m_savelist;
volatile int savelistCnt;
int savelistSize;
QMutex savelistMutex;
QSemaphore *savelistSem;
Session * SessionExists(SessionID session);
Day *AddSession(Session *s,Profile *p);

View File

@ -608,7 +608,7 @@ EventDataType Session::avg(ChannelID id)
m_avg[id]=val;
return val;
}
EventDataType Session::cph(ChannelID id)
EventDataType Session::cph(ChannelID id) // count per hour
{
QHash<ChannelID,EventDataType>::iterator i=m_cph.find(id);
if (i!=m_cph.end())
@ -620,7 +620,7 @@ EventDataType Session::cph(ChannelID id)
m_cph[id]=val;
return val;
}
EventDataType Session::sph(ChannelID id)
EventDataType Session::sph(ChannelID id) // sum per hour
{
QHash<ChannelID,EventDataType>::iterator i=m_sph.find(id);
if (i!=m_sph.end())
@ -632,7 +632,7 @@ EventDataType Session::sph(ChannelID id)
return val;
}
EventDataType Session::p90(ChannelID id)
EventDataType Session::p90(ChannelID id) // 90th Percentile
{
QHash<ChannelID,EventDataType>::iterator i=m_90p.find(id);
if (i!=m_90p.end())

View File

@ -68,9 +68,7 @@ private:
gGraph *PRD,*FRW,*GAHI,*TAP,*LEAK,*SF,*TAP_EAP,*TAP_IAP,*PULSE,*SPO2,
*SNORE,*RR,*MP,*MV,*TV,*FLG,*PTB,*OF,*INTPULSE,*INTSPO2, *THPR,
*PLETHY,*TI,*TE, *RE, *IE, *BC, *UC;
gBarChart *bc,*uc;
*PLETHY,*TI,*TE, *RE, *IE;
QList<Layer *> OXIData;
QList<Layer *> CPAPData;

View File

@ -397,7 +397,7 @@ void MainWindow::on_actionEnable_Multithreading_toggled(bool checked)
{
pref["EnableMultithreading"]=checked;
if (checked) {
qDebug() << "Multithreading feature is disabled due to it currently being useless.";
//qDebug() << "Multithreading feature is disabled due to it currently being useless.";
}
}

View File

@ -53,8 +53,11 @@ Overview::Overview(QWidget *parent,gGraphView * shared) :
layout->layout();
const int default_height=180;
AHI=new gGraph(GraphView,"AHI Chart",default_height,0);
UC=new gGraph(GraphView,"Usage Chart",default_height,0);
AHI=new gGraph(GraphView,"AHI",default_height,0);
UC=new gGraph(GraphView,"Usage",default_height,0);
PR=new gGraph(GraphView,"Pressure",default_height,0);
LK=new gGraph(GraphView,"Leaks",default_height,0);
uc=new UsageChart(profile);
UC->AddLayer(new gYAxis(),LayerLeft,gYAxis::Margin);
gXAxis *gx=new gXAxis();
@ -65,7 +68,6 @@ Overview::Overview(QWidget *parent,gGraphView * shared) :
bc=new AHIChart(profile);
//bc->setProfile(profile);
bc->addSlice(CPAP_Hypopnea,QColor("blue"));
bc->addSlice(CPAP_Apnea,QColor("dark green"));
bc->addSlice(CPAP_Obstructive,QColor("#40c0ff"));
@ -77,6 +79,30 @@ Overview::Overview(QWidget *parent,gGraphView * shared) :
AHI->AddLayer(bc);
AHI->AddLayer(new gXGrid());
pr=new AvgChart(profile);
pr->addSlice(CPAP_Pressure,QColor("dark green"));
//pr->addSlice(CPAP_EPAP,QColor("dark yellow"));
//pr->addSlice(CPAP_IPAP,QColor("red"));
PR->AddLayer(new gYAxis(),LayerLeft,gYAxis::Margin);
gx=new gXAxis();
gx->setUtcFix(true);
PR->AddLayer(gx,LayerBottom,0,gXAxis::Margin);
PR->AddLayer(pr);
PR->AddLayer(new gXGrid());
lk=new AvgChart(profile);
lk->addSlice(CPAP_Leak,QColor("gold"));
//lk->addSlice(CPAP_Leak,QColor("dark yellow"));
//pr->addSlice(CPAP_IPAP,QColor("red"));
LK->AddLayer(new gYAxis(),LayerLeft,gYAxis::Margin);
gx=new gXAxis();
gx->setUtcFix(true);
LK->AddLayer(gx,LayerBottom,0,gXAxis::Margin);
LK->AddLayer(lk);
LK->AddLayer(new gXGrid());
//ReloadGraphs();
}
@ -87,15 +113,13 @@ Overview::~Overview()
}
void Overview::ReloadGraphs()
{
bc->SetDay(NULL);
AHI->MinX();
AHI->MaxX();
/*bc->SetDay(NULL);
uc->SetDay(NULL);
UC->MinX();
UC->MaxX();
pr->SetDay(NULL);
lk->SetDay(NULL); */
GraphView->setDay(NULL);
GraphView->ResetBounds();
// GraphView->ResetBounds();
}
/*
ui->setupUi(this);

View File

@ -51,9 +51,11 @@ private:
void UpdateHTML();
//SessionTimes *session_times;
gGraph *AHI,*UC;
gGraph *AHI,*UC,*PR,*LK;
AHIChart *bc;
UsageChart *uc;
AvgChart *pr;
AvgChart *lk;
//,*PRESSURE,*LEAK,*SESSTIMES;
//Layer *prmax,*prmin,*iap,*eap,*pr,*sesstime;

View File

@ -29,7 +29,7 @@
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>1</number>
<number>0</number>
</property>
<widget class="QWidget" name="profileTab">
<attribute name="title">
@ -192,10 +192,10 @@
</sizepolicy>
</property>
<property name="toolTip">
<string>Used in BMI calculations</string>
<string>Used in BMI calculations. Americans, please us decimal inches here, unless you speak metric.</string>
</property>
<property name="minimum">
<double>40.000000000000000</double>
<double>0.000000000000000</double>
</property>
<property name="maximum">
<double>299.990000000000009</double>