[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: [calligra] plan: Cache performance data (bcws/bcwp/acwp)
From: Dag Andersen <danders () get2net ! dk>
Date: 2012-08-28 9:56:33
Message-ID: 20120828095633.D22DDA60A6 () git ! kde ! org
[Download RAW message or body]
Git commit 900b95e0c138bbd94ffcff07159f07f66cf074f8 by Dag Andersen.
Committed on 27/08/2012 at 09:33.
Pushed by danders into branch 'master'.
Cache performance data (bcws/bcwp/acwp)
M +2 -2 plan/kptpart.cpp
M +82 -24 plan/libs/kernel/kptnode.cpp
M +24 -4 plan/libs/kernel/kptnode.h
M +42 -34 plan/libs/kernel/kptproject.cpp
M +3 -3 plan/libs/kernel/kptproject.h
M +18 -7 plan/libs/kernel/kptschedule.cpp
M +25 -1 plan/libs/kernel/kptschedule.h
M +106 -87 plan/libs/kernel/kpttask.cpp
M +7 -4 plan/libs/kernel/kpttask.h
http://commits.kde.org/calligra/900b95e0c138bbd94ffcff07159f07f66cf074f8
diff --git a/plan/kptpart.cpp b/plan/kptpart.cpp
index 6b832e0..b774bba 100644
--- a/plan/kptpart.cpp
+++ b/plan/kptpart.cpp
@@ -145,12 +145,12 @@ void Part::configChanged()
void Part::setProject( Project *project )
{
if ( m_project ) {
- disconnect( m_project, SIGNAL( changed() ), this, SIGNAL( changed() ) );
+ disconnect( m_project, SIGNAL( projectChanged() ), this, SIGNAL( changed() ) );
delete m_project;
}
m_project = project;
if ( m_project ) {
- connect( m_project, SIGNAL( changed() ), this, SIGNAL( changed() ) );
+ connect( m_project, SIGNAL( projectChanged() ), this, SIGNAL( changed() ) );
// m_project->setConfig( config() );
m_project->setSchedulerPlugins( m_schedulerPlugins );
}
diff --git a/plan/libs/kernel/kptnode.cpp b/plan/libs/kernel/kptnode.cpp
index 82e8d88..ee5039a 100644
--- a/plan/libs/kernel/kptnode.cpp
+++ b/plan/libs/kernel/kptnode.cpp
@@ -197,7 +197,7 @@ void Node::takeChildNode( Node *node) {
}
node->setParentNode(0);
if ( t != type() ) {
-// changed(); Note: handled by project
+ changed( Type );
}
}
@@ -211,7 +211,7 @@ void Node::takeChildNode( int number ) {
}
}
if ( t != type() ) {
-// changed(); Note: handled by project
+ changed( Type );
}
}
@@ -223,7 +223,7 @@ void Node::insertChildNode( int index, Node *node ) {
m_nodes.insert(index,node);
node->setParentNode( this );
if ( t != type() ) {
-// changed(); Note: handled by project
+ changed( Type );
}
}
@@ -234,14 +234,14 @@ void Node::addChildNode( Node *node, Node *after) {
m_nodes.append(node);
node->setParentNode( this );
if ( t != type() ) {
-// changed(); Note: handled by project
+ changed( Type );
}
return;
}
m_nodes.insert(index+1, node);
node->setParentNode(this);
if ( t != type() ) {
-// changed(); Note: handled by project
+ changed( Type );
}
}
@@ -1187,7 +1187,7 @@ void Node::setCurrentSchedule(long id) {
void Node::setStartupCost(double cost)
{
m_startupCost = cost;
- changed();
+ changed(StartupCost);
}
void Node::setStartupAccount(Account *acc)
@@ -1203,7 +1203,7 @@ void Node::setStartupAccount(Account *acc)
void Node::setShutdownCost(double cost)
{
m_shutdownCost = cost;
- changed();
+ changed(ShutdownCost);
}
void Node::setShutdownAccount(Account *acc)
@@ -1226,9 +1226,28 @@ void Node::setRunningAccount(Account *acc)
changed();
}
-void Node::changed(Node *node) {
- if (m_parent)
- m_parent->changed(node);
+void Node::changed(Node *node, int property) {
+ switch ( property) {
+ case Type:
+ case StartupCost:
+ case ShutdownCost:
+ case CompletionEntry:
+ case CompletionStarted:
+ case CompletionFinished:
+ case CompletionStartTime:
+ case CompletionFinishTime:
+ case CompletionPercentage:
+ case CompletionRemainingEffort:
+ case CompletionActualEffort:
+ foreach ( Schedule *s, m_schedules ) {
+ s->clearPerformanceCache();
+ }
+ break;
+ default: break;
+ }
+ if (m_parent) {
+ m_parent->changed(node, property);
+ }
}
Duration Node::plannedEffort( const Resource *resource, long id, EffortCostCalculationType type ) const
@@ -1267,31 +1286,70 @@ EffortCost Node::plannedCost( long id, EffortCostCalculationType type ) const
return ec;
}
-EffortCostMap Node::bcwsPrDay( long int id, KPlato::EffortCostCalculationType type ) const
+EffortCostMap Node::bcwsPrDay( long int id, EffortCostCalculationType type ) const
{
- EffortCostMap ec;
- foreach ( Node *n, m_nodes ) {
- ec += n->bcwsPrDay( id, type );
+ return const_cast<Node*>( this )->bcwsPrDay( id, type );
+}
+
+EffortCostMap Node::bcwsPrDay( long int id, EffortCostCalculationType type )
+{
+ Schedule *s = schedule( id );
+ if ( s == 0 ) {
+ return EffortCostMap();
}
- return ec;
+ EffortCostCache &ec = s->bcwsPrDayCache( type );
+ if ( ! ec.cached ) {
+ ec.effortcostmap = EffortCostMap();
+ foreach ( Node *n, m_nodes ) {
+ ec.effortcostmap += n->bcwsPrDay( id, type );
+ }
+ ec.cached = true;
+ }
+ return ec.effortcostmap;
}
-EffortCostMap Node::bcwpPrDay( long int id, KPlato::EffortCostCalculationType type ) const
+EffortCostMap Node::bcwpPrDay( long int id, EffortCostCalculationType type ) const
{
- EffortCostMap ec;
- foreach ( Node *n, m_nodes ) {
- ec += n->bcwpPrDay( id, type );
+ return const_cast<Node*>( this )->bcwpPrDay( id, type);
+}
+
+EffortCostMap Node::bcwpPrDay( long int id, EffortCostCalculationType type )
+{
+ Schedule *s = schedule( id );
+ if ( s == 0 ) {
+ return EffortCostMap();
}
- return ec;
+ EffortCostCache &ec = s->bcwpPrDayCache( type );
+ if ( ! ec.cached ) {
+ ec.effortcostmap = EffortCostMap();
+ foreach ( Node *n, m_nodes ) {
+ ec.effortcostmap += n->bcwpPrDay( id, type );
+ }
+ ec.cached = true;
+ }
+ return ec.effortcostmap;
}
EffortCostMap Node::acwp( long id, EffortCostCalculationType type ) const
{
- EffortCostMap ec;
- foreach ( Node *n, m_nodes ) {
- ec += n->acwp( id, type );
+ return const_cast<Node*>( this )->acwp( id, type );
+}
+
+EffortCostMap Node::acwp( long id, EffortCostCalculationType type )
+{
+ Schedule *s = schedule( id );
+ if ( s == 0 ) {
+ return EffortCostMap();
}
- return ec;
+ EffortCostCache &ec = s->acwpCache( type );
+ if ( ! ec.cached ) {
+ ec.effortcostmap = EffortCostMap();
+ foreach ( Node *n, m_nodes ) {
+ ec.effortcostmap += n->acwp( id, type );
+ }
+ ec.cached = true;
+ }
+ return ec.effortcostmap;
}
EffortCost Node::acwp( const QDate &date, long id ) const
diff --git a/plan/libs/kernel/kptnode.h b/plan/libs/kernel/kptnode.h
index 671458b..119b006 100644
--- a/plan/libs/kernel/kptnode.h
+++ b/plan/libs/kernel/kptnode.h
@@ -84,6 +84,20 @@ public:
State_NotScheduled = 2048
};
+ enum Properties {
+ Type,
+ StartupCost,
+ ShutdownCost,
+ CompletionEntry,
+ CompletionStarted,
+ CompletionFinished,
+ CompletionStartTime,
+ CompletionFinishTime,
+ CompletionPercentage,
+ CompletionRemainingEffort,
+ CompletionActualEffort
+ };
+
Node(Node *parent = 0);
Node(const Node &node, Node *parent = 0);
@@ -333,22 +347,28 @@ public:
virtual double budgetedCostPerformed( const QDate &, long = CURRENTSCHEDULE ) const { return 0.0; };
/// Return map of Budgeted Cost of Work Scheduled pr day
+ virtual EffortCostMap bcwsPrDay( long id = CURRENTSCHEDULE, EffortCostCalculationType type = \
ECCT_All ); + /// Return map of Budgeted Cost of Work Scheduled pr day
virtual EffortCostMap bcwsPrDay( long id = CURRENTSCHEDULE, EffortCostCalculationType type = \
ECCT_All ) const; /// Budgeted Cost of Work Scheduled
virtual double bcws( const QDate &/*date*/, long id = CURRENTSCHEDULE ) const { Q_UNUSED(id); return \
0.0; }
/// Return map of Budgeted Cost of Work Scheduled pr day (also includes bcws pr day)
+ virtual EffortCostMap bcwpPrDay( long id = CURRENTSCHEDULE, EffortCostCalculationType type = \
ECCT_All ); + /// Return map of Budgeted Cost of Work Scheduled pr day (also includes bcws pr day)
virtual EffortCostMap bcwpPrDay( long id = CURRENTSCHEDULE, EffortCostCalculationType type = \
ECCT_All ) const; /// Budgeted Cost of Work Performed
virtual double bcwp( long id ) const { Q_UNUSED(id); return 0.0; }
/// Budgeted Cost of Work Performed ( up to @p date )
virtual double bcwp( const QDate &/*date*/, long id = CURRENTSCHEDULE ) const { Q_UNUSED(id); return \
0.0; }
-
+
+ /// Return a map of Actual effort and Cost of Work Performed
+ virtual EffortCostMap acwp( long id = CURRENTSCHEDULE, EffortCostCalculationType type = ECCT_All );
/// Return a map of Actual effort and Cost of Work Performed
virtual EffortCostMap acwp( long id = CURRENTSCHEDULE, EffortCostCalculationType type = ECCT_All ) \
const; /// Return Actual effort and Cost of Work Performed upto @date
virtual EffortCost acwp( const QDate &date, long id = CURRENTSCHEDULE ) const;
-
+
/// Effort based performance index
virtual double effortPerformanceIndex(const QDate &/*date*/, long /*id*/ = CURRENTSCHEDULE ) const { \
return 0.0; } /// Schedule performance index
@@ -583,7 +603,7 @@ public:
virtual void addParentProxyRelation(Node *, const Relation *) {}
virtual void addChildProxyRelation(Node *, const Relation *) {}
- virtual void changed() { changed( this ); }
+ virtual void changed( int property = -1 ) { changed( this, property ); }
Duration getmDurationForward(){ return this->m_durationForward;}
public slots:
@@ -600,7 +620,7 @@ protected:
// NOTE: Cannot use setCurrentSchedule() due to overload/casting problems
void setCurrentSchedulePtr(Schedule *schedule) { m_currentSchedule = schedule; }
- virtual void changed(Node *node);
+ virtual void changed(Node *node, int property = -1 );
QList<Node*> m_nodes;
QList<Relation*> m_dependChildNodes;
diff --git a/plan/libs/kernel/kptproject.cpp b/plan/libs/kernel/kptproject.cpp
index ee92e50..33854c3 100644
--- a/plan/libs/kernel/kptproject.cpp
+++ b/plan/libs/kernel/kptproject.cpp
@@ -200,7 +200,7 @@ void Project::calculate( const DateTime &dt )
cs->notScheduled = false;
calcFreeFloat();
emit scheduleChanged( cs );
- emit changed();
+ emit projectChanged();
} else if ( type() == Type_Subproject ) {
kWarning() << "Subprojects not implemented";
} else {
@@ -241,7 +241,7 @@ void Project::calculate( ScheduleManager &sm )
emit sigCalculationFinished( this, &sm );
emit scheduleManagerChanged( &sm );
emit projectCalculated( &sm );
- emit changed();
+ emit projectChanged();
sm.setScheduling( false );
}
@@ -352,7 +352,7 @@ void Project::calculate()
cs->notScheduled = false;
calcFreeFloat();
emit scheduleChanged( cs );
- emit changed();
+ emit projectChanged();
} else if ( type() == Type_Subproject ) {
kWarning() << "Subprojects not implemented";
} else {
@@ -368,7 +368,7 @@ void Project::finishCalculation( ScheduleManager &sm )
cs->notScheduled = false;
calcFreeFloat();
emit scheduleChanged( cs );
- emit changed();
+ emit projectChanged();
}
void Project::setProgress( int progress, ScheduleManager *sm )
@@ -1265,7 +1265,7 @@ void Project::addResourceGroup( ResourceGroup *group, int index )
r->setProject( this );
}
emit resourceGroupAdded( group );
- emit changed();
+ emit projectChanged();
}
ResourceGroup *Project::takeResourceGroup( ResourceGroup *group )
@@ -1285,7 +1285,7 @@ ResourceGroup *Project::takeResourceGroup( ResourceGroup *group )
removeResourceId( r->id() );
}
emit resourceGroupRemoved( g );
- emit changed();
+ emit projectChanged();
return g;
}
@@ -1301,7 +1301,7 @@ void Project::addResource( ResourceGroup *group, Resource *resource, int index )
group->addResource( i, resource, 0 );
setResourceId( resource );
emit resourceAdded( resource );
- emit changed();
+ emit projectChanged();
}
Resource *Project::takeResource( ResourceGroup *group, Resource *resource )
@@ -1319,7 +1319,7 @@ Resource *Project::takeResource( ResourceGroup *group, Resource *resource )
kWarning() << "Cound not take resource from group";
}
emit resourceRemoved( resource );
- emit changed();
+ emit projectChanged();
return r;
}
@@ -1400,7 +1400,7 @@ bool Project::addSubTask( Node* task, int index, Node* parent, bool emitSignal )
connect( this, SIGNAL( standardWorktimeChanged( StandardWorktime* ) ), task, SLOT( \
slotStandardWorktimeChanged( StandardWorktime* ) ) ); if ( emitSignal ) {
emit nodeAdded( task );
- emit changed();
+ emit projectChanged();
if ( p != this && p->numChildren() == 1 ) {
emit nodeChanged( p );
}
@@ -1422,7 +1422,7 @@ void Project::takeTask( Node *node, bool emitSignal )
parent->takeChildNode( node );
if ( emitSignal ) {
emit nodeRemoved( node );
- emit changed();
+ emit projectChanged();
if ( parent != this && parent->type() != Node::Type_Summarytask ) {
emit nodeChanged( parent );
}
@@ -1858,6 +1858,10 @@ QStringList Project::resourceNameList() const
EffortCostMap Project::plannedEffortCostPrDay( const QDate & start, const QDate &end, long id, \
EffortCostCalculationType typ ) const {
//kDebug(planDbg())<<start<<end<<id;
+ Schedule *s = schedule( id );
+ if ( s == 0 ) {
+ return EffortCostMap();
+ }
EffortCostMap ec;
QListIterator<Node*> it( childNodeIterator() );
while ( it.hasNext() ) {
@@ -2087,7 +2091,7 @@ void Project::addCalendar( Calendar *calendar, Calendar *parent, int index )
}
setCalendarId( calendar );
emit calendarAdded( calendar );
- emit changed();
+ emit projectChanged();
}
void Project::takeCalendar( Calendar *calendar )
@@ -2107,7 +2111,7 @@ void Project::takeCalendar( Calendar *calendar )
}
emit calendarRemoved( calendar );
calendar->setProject( 0 );
- emit changed();
+ emit projectChanged();
}
int Project::indexOf( const Calendar *calendar ) const
@@ -2191,7 +2195,7 @@ void Project::setDefaultCalendar( Calendar *cal )
cal->setDefault( true );
}
emit defaultCalendarChanged( cal );
- emit changed();
+ emit projectChanged();
}
void Project::setStandardWorktime( StandardWorktime * worktime )
@@ -2306,7 +2310,7 @@ void Project::setWbsDefinition( const WBSDefinition &def )
//kDebug(planDbg());
m_wbsDefinition = def;
emit wbsDefinitionChanged();
- emit changed();
+ emit projectChanged();
}
QString Project::generateWBSCode( QList<int> &indexes ) const
@@ -2338,7 +2342,7 @@ void Project::setCurrentSchedule( long id )
r->setCurrentSchedule( id );
}
emit currentScheduleChanged();
- emit changed();
+ emit projectChanged();
}
ScheduleManager *Project::scheduleManager( long id ) const
@@ -2417,7 +2421,7 @@ void Project::addScheduleManager( ScheduleManager *sm, ScheduleManager *parent,
m_managerIdMap.insert( sm->managerId(), sm );
emit scheduleManagerAdded( sm );
- emit changed();
+ emit projectChanged();
//kDebug(planDbg())<<"Added:"<<sm->name()<<", now"<<m_managers.count();
}
@@ -2437,7 +2441,7 @@ int Project::takeScheduleManager( ScheduleManager *sm )
sm->setParentManager( 0 );
m_managerIdMap.remove( sm->managerId() );
emit scheduleManagerRemoved( sm );
- emit changed();
+ emit projectChanged();
}
} else {
index = indexOf( sm );
@@ -2446,7 +2450,7 @@ int Project::takeScheduleManager( ScheduleManager *sm )
m_managers.removeAt( indexOf( sm ) );
m_managerIdMap.remove( sm->managerId() );
emit scheduleManagerRemoved( sm );
- emit changed();
+ emit projectChanged();
}
}
return index;
@@ -2553,34 +2557,38 @@ void Project::insertCalendarId( const QString &id, Calendar *calendar )
calendarIdDict.insert( id, calendar );
}
-void Project::changed( Node *node )
+void Project::changed( Node *node, int property )
{
if ( m_parent == 0 ) {
- emit nodeChanged( node );
- emit changed();
+ Node::changed( node, property ); // reset cache
+ if ( property != Node::Type ) {
+ // add/remove node is handled elsewhere
+ emit nodeChanged( node );
+ emit projectChanged();
+ }
return;
}
- Node::changed( node );
+ Node::changed( node, property );
}
void Project::changed( ResourceGroup *group )
{
//kDebug(planDbg());
emit resourceGroupChanged( group );
- emit changed();
+ emit projectChanged();
}
void Project::changed( ScheduleManager *sm )
{
emit scheduleManagerChanged( sm );
- emit changed();
+ emit projectChanged();
}
void Project::changed( MainSchedule *sch )
{
//kDebug(planDbg())<<sch->id();
emit scheduleChanged( sch );
- emit changed();
+ emit projectChanged();
}
void Project::sendScheduleToBeAdded( const ScheduleManager *sm, int row )
@@ -2592,7 +2600,7 @@ void Project::sendScheduleAdded( const MainSchedule *sch )
{
//kDebug(planDbg())<<sch->id();
emit scheduleAdded( sch );
- emit changed();
+ emit projectChanged();
}
void Project::sendScheduleToBeRemoved( const MainSchedule *sch )
@@ -2605,25 +2613,25 @@ void Project::sendScheduleRemoved( const MainSchedule *sch )
{
//kDebug(planDbg())<<sch->id();
emit scheduleRemoved( sch );
- emit changed();
+ emit projectChanged();
}
void Project::changed( Resource *resource )
{
emit resourceChanged( resource );
- emit changed();
+ emit projectChanged();
}
void Project::changed( Calendar *cal )
{
emit calendarChanged( cal );
- emit changed();
+ emit projectChanged();
}
void Project::changed( StandardWorktime *w )
{
emit standardWorktimeChanged( w );
- emit changed();
+ emit projectChanged();
}
bool Project::addRelation( Relation *rel, bool check )
@@ -2638,7 +2646,7 @@ bool Project::addRelation( Relation *rel, bool check )
rel->parent()->addDependChildNode( rel );
rel->child()->addDependParentNode( rel );
emit relationAdded( rel );
- emit changed();
+ emit projectChanged();
return true;
}
@@ -2648,7 +2656,7 @@ void Project::takeRelation( Relation *rel )
rel->parent() ->takeDependChildNode( rel );
rel->child() ->takeDependParentNode( rel );
emit relationRemoved( rel );
- emit changed();
+ emit projectChanged();
}
void Project::setRelationType( Relation *rel, Relation::Type type )
@@ -2656,7 +2664,7 @@ void Project::setRelationType( Relation *rel, Relation::Type type )
emit relationToBeModified( rel );
rel->setType( type );
emit relationModified( rel );
- emit changed();
+ emit projectChanged();
}
void Project::setRelationLag( Relation *rel, const Duration &lag )
@@ -2664,7 +2672,7 @@ void Project::setRelationLag( Relation *rel, const Duration &lag )
emit relationToBeModified( rel );
rel->setLag( lag );
emit relationModified( rel );
- emit changed();
+ emit projectChanged();
}
QList<Node*> Project::flatNodeList( Node *parent )
diff --git a/plan/libs/kernel/kptproject.h b/plan/libs/kernel/kptproject.h
index 82aa0dd..b278438 100644
--- a/plan/libs/kernel/kptproject.h
+++ b/plan/libs/kernel/kptproject.h
@@ -520,7 +520,7 @@ public slots:
signals:
/// Emitted when anything in the project is changed (use with care)
- void changed();
+ void projectChanged();
/// Emitted when the WBS code definition has changed. This may change all nodes.
void wbsDefinitionChanged();
/// Emitted when a schedule has been calculated
@@ -638,8 +638,8 @@ protected:
protected:
friend class KPlatoXmlLoaderBase;
-
- virtual void changed(Node *node);
+ using Node::changed;
+ virtual void changed(Node *node, int property = -1);
Accounts m_accounts;
QList<ResourceGroup*> m_resourceGroups;
diff --git a/plan/libs/kernel/kptschedule.cpp b/plan/libs/kernel/kptschedule.cpp
index 10ee3d0..0682bb8 100644
--- a/plan/libs/kernel/kptschedule.cpp
+++ b/plan/libs/kernel/kptschedule.cpp
@@ -233,8 +233,6 @@ void Schedule::initiateCalculation()
effortNotMet = false;
workStartTime = DateTime();
workEndTime = DateTime();
-
-
}
void Schedule::calcResourceOverbooked()
@@ -518,15 +516,21 @@ void Schedule::copyAppointments( Schedule::CalculationMode from, Schedule::Calcu
}
}
-
EffortCostMap Schedule::bcwsPrDay( EffortCostCalculationType type ) const
{
+ return const_cast<Schedule*>( this )->bcwsPrDay( type );
+}
+
+EffortCostMap Schedule::bcwsPrDay( EffortCostCalculationType type )
+{
//kDebug(planDbg())<<m_name<<m_appointments;
- EffortCostMap ec;
- foreach ( Appointment *a, m_appointments ) {
- ec += a->plannedPrDay( a->startTime().date(), a->endTime().date(), type );
+ EffortCostCache &ec = m_bcwsPrDay[ (int)type ];
+ if ( ! ec.cached ) {
+ foreach ( Appointment *a, m_appointments ) {
+ ec.effortcostmap += a->plannedPrDay( a->startTime().date(), a->endTime().date(), type );
+ }
}
- return ec;
+ return ec.effortcostmap;
}
EffortCostMap Schedule::plannedEffortCostPrDay( const QDate &start, const QDate &end, \
EffortCostCalculationType type ) const @@ -669,6 +673,13 @@ QString Schedule::Log::formatMsg() const
return s;
}
+void Schedule::clearPerformanceCache()
+{
+ m_bcwsPrDay.clear();
+ m_bcwpPrDay.clear();
+ m_acwp.clear();
+}
+
//-------------------------------------------------
NodeSchedule::NodeSchedule()
: Schedule(),
diff --git a/plan/libs/kernel/kptschedule.h b/plan/libs/kernel/kptschedule.h
index dabcd1c..05d4d40 100644
--- a/plan/libs/kernel/kptschedule.h
+++ b/plan/libs/kernel/kptschedule.h
@@ -51,6 +51,14 @@ class XMLLoaderObject;
class SchedulerPlugin;
class KPlatoXmlLoaderBase;
+/// Caches effortcost data (bcws, bcwp, acwp)
+class EffortCostCache {
+public:
+ EffortCostCache() : cached( false ) {}
+ bool cached;
+ EffortCostMap effortcostmap;
+};
+
/**
* The Schedule class holds data calculated during project
* calculation and scheduling, eg start- and end-times and
@@ -153,7 +161,8 @@ public:
virtual QList<Resource*> resources() const;
/// Return the resource names that has appointments to this schedule
virtual QStringList resourceNameList() const;
-
+
+ virtual EffortCostMap bcwsPrDay( EffortCostCalculationType type = ECCT_All );
virtual EffortCostMap bcwsPrDay( EffortCostCalculationType type = ECCT_All ) const;
virtual EffortCostMap plannedEffortCostPrDay( const QDate &start, const QDate &end, \
EffortCostCalculationType type = ECCT_All ) const;
virtual EffortCostMap plannedEffortCostPrDay( const Resource *resource, const QDate &start, const \
QDate &end, EffortCostCalculationType type = ECCT_All ) const; @@ -250,6 +259,8 @@ public:
virtual void incProgress() { if ( m_parent ) m_parent->incProgress(); }
+ void clearPerformanceCache();
+
protected:
virtual void changed( Schedule * /*sch*/ ) {}
@@ -334,6 +345,19 @@ protected:
Duration positiveFloat;
Duration negativeFloat;
Duration freeFloat;
+
+ EffortCostCache &bcwsPrDayCache( int type ) {
+ return m_bcwsPrDay[ type ];
+ }
+ EffortCostCache &bcwpPrDayCache( int type ) {
+ return m_bcwpPrDay[ type ];
+ }
+ EffortCostCache &acwpCache( int type ) {
+ return m_acwp[ type ];
+ }
+ QMap<int, EffortCostCache> m_bcwsPrDay;
+ QMap<int, EffortCostCache> m_bcwpPrDay;
+ QMap<int, EffortCostCache> m_acwp;
};
/**
diff --git a/plan/libs/kernel/kpttask.cpp b/plan/libs/kernel/kpttask.cpp
index 26981b8..23ae2ab 100644
--- a/plan/libs/kernel/kpttask.cpp
+++ b/plan/libs/kernel/kpttask.cpp
@@ -747,7 +747,7 @@ double Task::bcws( const QDate &date, long id ) const
return c;
}
-EffortCostMap Task::bcwsPrDay( long int id, KPlato::EffortCostCalculationType typ ) const
+EffortCostMap Task::bcwsPrDay( long int id, EffortCostCalculationType typ )
{
//kDebug(planDbg());
if (type() == Node::Type_Summarytask) {
@@ -757,17 +757,22 @@ EffortCostMap Task::bcwsPrDay( long int id, KPlato::EffortCostCalculationType ty
if ( s == 0 ) {
return EffortCostMap();
}
- EffortCostMap ec = s->bcwsPrDay( typ );
- if ( m_startupCost > 0.0 ) {
- ec.add( s->startTime.date(), Duration::zeroDuration, m_startupCost );
- }
- if ( m_shutdownCost > 0.0 ) {
- ec.add( s->endTime.date(), Duration::zeroDuration, m_shutdownCost );
+ EffortCostCache &cache = s->bcwsPrDayCache( typ );
+ if ( ! cache.cached ) {
+ EffortCostMap ec = s->bcwsPrDay( typ );
+ if ( m_startupCost > 0.0 ) {
+ ec.add( s->startTime.date(), Duration::zeroDuration, m_startupCost );
+ }
+ if ( m_shutdownCost > 0.0 ) {
+ ec.add( s->endTime.date(), Duration::zeroDuration, m_shutdownCost );
+ }
+ cache.effortcostmap = ec;
+ cache.cached = true;
}
- return ec;
+ return cache.effortcostmap;
}
-EffortCostMap Task::bcwpPrDay( long int id, KPlato::EffortCostCalculationType typ ) const
+EffortCostMap Task::bcwpPrDay( long int id, EffortCostCalculationType typ )
{
//kDebug(planDbg());
if ( type() == Node::Type_Summarytask ) {
@@ -777,59 +782,64 @@ EffortCostMap Task::bcwpPrDay( long int id, KPlato::EffortCostCalculationType ty
if ( s == 0 ) {
return EffortCostMap();
}
- EffortCostMap e = s->bcwsPrDay( typ );
- if ( completion().isStarted() && ! e.isEmpty() ) {
- // calculate bcwp on bases of bcws *without* startup/shutdown cost
- double totEff = e.totalEffort().toDouble( Duration::Unit_h );
- double totCost = e.totalCost();
- QDate sd = completion().entries().keys().value( 0 );
- if ( ! sd.isValid() || e.startDate() < sd ) {
- sd = e.startDate();
- }
- QDate ed = qMax( e.endDate(), completion().entryDate() );
- for ( QDate d = sd; d <= ed; d = d.addDays( 1 ) ) {
- double p = (double)(completion().percentFinished( d )) / 100.0;
- EffortCost ec = e.days()[ d ];
- ec.setBcwpEffort( totEff * p );
- ec.setBcwpCost( totCost * p );
- e.insert( d, ec );
- }
- }
- if ( typ != ECCT_Work ) {
- // add bcws startup/shutdown cost
- if ( m_startupCost > 0.0 ) {
- e.add( s->startTime.date(), Duration::zeroDuration, m_startupCost );
- }
- if ( m_shutdownCost > 0.0 ) {
- e.add( s->endTime.date(), Duration::zeroDuration, m_shutdownCost );
- }
- // add bcwp startup/shutdown cost
- if ( m_shutdownCost > 0.0 && completion().finishIsValid() ) {
- QDate finish = completion().finishTime().date();
- e.addBcwpCost( finish, m_shutdownCost );
- kDebug(planDbg())<<"addBcwpCost:"<<finish<<m_shutdownCost;
- // bcwp is cumulative so add to all entries after finish (in case task finished early)
- for ( EffortCostDayMap::const_iterator it = e.days().constBegin(); it != \
e.days().constEnd(); ++it ) {
- const QDate date = it.key();
- if ( date > finish ) {
- e.addBcwpCost( date, m_shutdownCost );
- kDebug(planDbg())<<"addBcwpCost:"<<date<<m_shutdownCost;
+ EffortCostCache cache = s->bcwpPrDayCache( typ );
+ if ( ! cache.cached ) {
+ EffortCostMap e = bcwsPrDay( id, typ );
+ if ( completion().isStarted() && ! e.isEmpty() ) {
+ // calculate bcwp on bases of bcws *without* startup/shutdown cost
+ double totEff = e.totalEffort().toDouble( Duration::Unit_h );
+ double totCost = e.totalCost();
+ QDate sd = completion().entries().keys().value( 0 );
+ if ( ! sd.isValid() || e.startDate() < sd ) {
+ sd = e.startDate();
+ }
+ QDate ed = qMax( e.endDate(), completion().entryDate() );
+ for ( QDate d = sd; d <= ed; d = d.addDays( 1 ) ) {
+ double p = (double)(completion().percentFinished( d )) / 100.0;
+ EffortCost ec = e.days()[ d ];
+ ec.setBcwpEffort( totEff * p );
+ ec.setBcwpCost( totCost * p );
+ e.insert( d, ec );
+ }
+ }
+ if ( typ != ECCT_Work ) {
+ // add bcws startup/shutdown cost
+ if ( m_startupCost > 0.0 ) {
+ e.add( s->startTime.date(), Duration::zeroDuration, m_startupCost );
+ }
+ if ( m_shutdownCost > 0.0 ) {
+ e.add( s->endTime.date(), Duration::zeroDuration, m_shutdownCost );
+ }
+ // add bcwp startup/shutdown cost
+ if ( m_shutdownCost > 0.0 && completion().finishIsValid() ) {
+ QDate finish = completion().finishTime().date();
+ e.addBcwpCost( finish, m_shutdownCost );
+ kDebug(planDbg())<<"addBcwpCost:"<<finish<<m_shutdownCost;
+ // bcwp is cumulative so add to all entries after finish (in case task finished early)
+ for ( EffortCostDayMap::const_iterator it = e.days().constBegin(); it != \
e.days().constEnd(); ++it ) { + const QDate date = it.key();
+ if ( date > finish ) {
+ e.addBcwpCost( date, m_shutdownCost );
+ kDebug(planDbg())<<"addBcwpCost:"<<date<<m_shutdownCost;
+ }
}
}
- }
- if ( m_startupCost > 0.0 && completion().startIsValid() ) {
- QDate start = completion().startTime().date();
- e.addBcwpCost( start, m_startupCost );
- // bcwp is cumulative so add to all entries after start
- for ( EffortCostDayMap::const_iterator it = e.days().constBegin(); it != \
e.days().constEnd(); ++it ) {
- const QDate date = it.key();
- if ( date > start ) {
- e.addBcwpCost( date, m_startupCost );
+ if ( m_startupCost > 0.0 && completion().startIsValid() ) {
+ QDate start = completion().startTime().date();
+ e.addBcwpCost( start, m_startupCost );
+ // bcwp is cumulative so add to all entries after start
+ for ( EffortCostDayMap::const_iterator it = e.days().constBegin(); it != \
e.days().constEnd(); ++it ) { + const QDate date = it.key();
+ if ( date > start ) {
+ e.addBcwpCost( date, m_startupCost );
+ }
}
}
}
+ cache.effortcostmap = e;
+ cache.cached = true;
}
- return e;
+ return cache.effortcostmap;
}
Duration Task::budgetedWorkPerformed( const QDate &date, long id ) const
@@ -880,34 +890,43 @@ double Task::bcwp( const QDate &date, long id ) const
return budgetedCostPerformed( date, id );
}
-EffortCostMap Task::acwp( long int id, KPlato::EffortCostCalculationType typ ) const
+EffortCostMap Task::acwp( long int id, KPlato::EffortCostCalculationType typ )
{
if ( type() == Node::Type_Summarytask ) {
return Node::acwp( id, typ );
}
- //kDebug(planDbg())<<m_name<<completion().entrymode();
- switch ( completion().entrymode() ) {
- case Completion::FollowPlan:
- //TODO
- break;
- case Completion::EnterCompleted:
- //hmmm
- default: {
- EffortCostMap m = completion().actualEffortCost( id );
- if ( completion().isStarted() ) {
- EffortCost e;
- e.setCost( m_startupCost );
- m.add( completion().startTime().date(), e );
- }
- if ( completion().isFinished() ) {
- EffortCost e;
- e.setCost( m_shutdownCost );
- m.add( completion().finishTime().date(), e );
+ Schedule *s = schedule( id );
+ if ( s == 0 ) {
+ return EffortCostMap();
+ }
+ EffortCostCache ec = s->acwpCache( typ );
+ if ( ! ec.cached ) {
+ //kDebug(planDbg())<<m_name<<completion().entrymode();
+ EffortCostMap m;
+ switch ( completion().entrymode() ) {
+ case Completion::FollowPlan:
+ //TODO
+ break;
+ case Completion::EnterCompleted:
+ //hmmm
+ default: {
+ m = completion().actualEffortCost( id );
+ if ( completion().isStarted() ) {
+ EffortCost e;
+ e.setCost( m_startupCost );
+ m.add( completion().startTime().date(), e );
+ }
+ if ( completion().isFinished() ) {
+ EffortCost e;
+ e.setCost( m_shutdownCost );
+ m.add( completion().finishTime().date(), e );
+ }
}
- return m;
}
+ ec.effortcostmap = m;
+ ec.cached = true;
}
- return EffortCostMap();
+ return ec.effortcostmap;
}
EffortCost Task::acwp( const QDate &date, long id ) const
@@ -2894,35 +2913,35 @@ Completion &Completion::operator=( const Completion &p )
return *this;
}
-void Completion::changed()
+void Completion::changed( int property)
{
if ( m_node ) {
- m_node->changed();
+ m_node->changed(property);
}
}
void Completion::setStarted( bool on )
{
m_started = on;
- changed();
+ changed(Node::CompletionStarted);
}
void Completion::setFinished( bool on )
{
m_finished = on;
- changed();
+ changed(Node::CompletionFinished);
}
void Completion::setStartTime( const DateTime &dt )
{
m_startTime = dt;
- changed();
+ changed(Node::CompletionStartTime);
}
void Completion::setFinishTime( const DateTime &dt )
{
m_finishTime = dt;
- changed();
+ changed(Node::CompletionFinishTime);
}
void Completion::setPercentFinished( const QDate &date, int value )
@@ -2935,7 +2954,7 @@ void Completion::setPercentFinished( const QDate &date, int value )
m_entries[ date ] = e;
}
e->percentFinished = value;
- changed();
+ changed(Node::CompletionPercentage);
}
void Completion::setRemainingEffort( const QDate &date, const Duration &value )
@@ -2948,7 +2967,7 @@ void Completion::setRemainingEffort( const QDate &date, const Duration &value )
m_entries[ date ] = e;
}
e->remainingEffort = value;
- changed();
+ changed(Node::CompletionRemainingEffort);
}
void Completion::setActualEffort( const QDate &date, const Duration &value )
@@ -2961,14 +2980,14 @@ void Completion::setActualEffort( const QDate &date, const Duration &value )
m_entries[ date ] = e;
}
e->totalPerformed = value;
- changed();
+ changed(Node::CompletionActualEffort);
}
void Completion::addEntry( const QDate &date, Entry *entry )
{
m_entries.insert( date, entry );
//kDebug(planDbg())<<m_entries.count()<<" added:"<<date;
- changed();
+ changed(Node::CompletionEntry);
}
QDate Completion::entryDate() const
diff --git a/plan/libs/kernel/kpttask.h b/plan/libs/kernel/kpttask.h
index 60cfb8f..57a045c 100644
--- a/plan/libs/kernel/kpttask.h
+++ b/plan/libs/kernel/kpttask.h
@@ -214,7 +214,7 @@ public:
UsedEffort *usedEffort( const Resource *r ) const { return m_usedEffort.value( \
const_cast<Resource*>( r ) ); }
const ResourceUsedEffortMap &usedEffortMap() const { return m_usedEffort; }
- void changed();
+ void changed( int propert = -1 );
Node *node() const { return m_node; }
void setNode( Node *node ) { m_node = node; }
@@ -459,21 +459,24 @@ public:
/// Returns the cost planned to be used to reach the actual percent finished
virtual double budgetedCostPerformed( const QDate &date, long id = CURRENTSCHEDULE ) const;
+ using Node::bcwsPrDay;
/// Return map of Budgeted Cost of Work Scheduled pr day
- virtual EffortCostMap bcwsPrDay( long id = CURRENTSCHEDULE, EffortCostCalculationType type = \
ECCT_All ) const; + virtual EffortCostMap bcwsPrDay( long id = CURRENTSCHEDULE, \
EffortCostCalculationType type = ECCT_All );
/// Budgeted Cost of Work Scheduled
virtual double bcws( const QDate &date, long id = CURRENTSCHEDULE ) const;
+ using Node::bcwpPrDay;
/// Return map of Budgeted Cost of Work Performed pr day (also includes bcwsPrDay)
- virtual EffortCostMap bcwpPrDay( long id = CURRENTSCHEDULE, EffortCostCalculationType type = \
ECCT_All ) const; + virtual EffortCostMap bcwpPrDay( long id = CURRENTSCHEDULE, \
EffortCostCalculationType type = ECCT_All ); /// Budgeted Cost of Work Performed
virtual double bcwp( long id = CURRENTSCHEDULE ) const;
/// Budgeted Cost of Work Performed ( up to @p date )
virtual double bcwp( const QDate &date, long id = CURRENTSCHEDULE ) const;
+ using Node::acwp;
/// Map of Actual Cost of Work Performed
- virtual EffortCostMap acwp( long id = CURRENTSCHEDULE, EffortCostCalculationType type = ECCT_All ) \
const; + virtual EffortCostMap acwp( long id = CURRENTSCHEDULE, EffortCostCalculationType type = \
ECCT_All ); /// Actual Cost of Work Performed up to dat
virtual EffortCost acwp( const QDate &date, long id = CURRENTSCHEDULE ) const;
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic