Fix RideFileCache threaded db access

The call to RideFile::getWeight() in RideFileCache
computation ends up with a call the read the measures
table in the DB. This is BAD since it is called from
a thread.

We now call getWeight() in the metric aggregator before
launching the ridefilecache computation -- this will cache
the weight and avoid db access.

I've also removed the duplicate code in the w/kg metric code
too and it should be marginally faster at computing metrics
now.

BIG THANKS TO ILJA BOOIJ FOR HIGHLIGHTING THIS, DESPITE MY
INITIAL SCEPTICISM. I OWE HIM A PINT (OR TWO) :)

Fixes #604
This commit is contained in:
Mark Liversedge
2013-05-19 19:06:28 +01:00
parent a89dc3bb97
commit 1aadc19f36
3 changed files with 14 additions and 25 deletions

View File

@@ -63,8 +63,9 @@
// 44 19 Apr 2013 Mark Liversedge Aerobic Decoupling precision reduced to 1pt
// 45 09 May 2013 Mark Liversedge Added 2,3,8 and 90m peak power for fatigue profiling
// 46 13 May 2013 Mark Liversedge Handle absence of speed in metric calculations
// 47 17 May 2013 Mark Liversedge Reimplementation of w/kg and ride->getWeight()
int DBSchemaVersion = 46;
int DBSchemaVersion = 47;
DBAccess::DBAccess(MainWindow* main, QDir home) : main(main), home(home)
{

View File

@@ -165,6 +165,8 @@ void MetricAggregator::refreshMetrics(QDateTime forceAfterThisDate)
if (ride != NULL) {
out << "Getting weight: " << name << "\r\n";
ride->getWeight();
out << "Updating statistics: " << name << "\r\n";
importRide(home, ride, name, zoneFingerPrint, (dbTimeStamp > 0));

View File

@@ -24,26 +24,6 @@
#include <math.h>
#include <QApplication>
// first use RideFile::startTime, then Measure then fallback to Global Setting
static double
getWeight(const MainWindow *main, const RideFile *ride)
{
// ride
double weight;
if ((weight = ride->getTag("Weight", "0.0").toDouble()) > 0) {
return weight;
}
// withings?
QList<SummaryMetrics> measures = main->metricDB->getAllMeasuresFor(QDateTime::fromString("Jan 1 00:00:00 1900"), ride->startTime());
if (measures.count()) {
return measures.last().getText("Weight", "0.0").toDouble();
}
// global options
return appsettings->cvalue(main->cyclist, GC_WEIGHT, "75.0").toString().toDouble(); // default to 75kg
}
class AverageWPK : public RideMetric {
Q_DECLARE_TR_FUNCTIONS(AverageWPK)
@@ -65,11 +45,14 @@ class AverageWPK : public RideMetric {
void compute(const RideFile *ride, const Zones *, int,
const HrZones *, int,
const QHash<QString,RideMetric*> &deps,
const MainWindow *main) {
const MainWindow *) {
// unconst naughty boy
RideFile *uride = const_cast<RideFile*>(ride);
// get thos dependencies
double secs = deps.value("workout_time")->value(true);
double weight = getWeight(main, ride);
double weight = uride->getWeight();
double ap = deps.value("average_power")->value(true);
// calclate watts per kilo
@@ -98,10 +81,13 @@ class PeakWPK : public RideMetric {
void compute(const RideFile *ride, const Zones *, int,
const HrZones *, int,
const QHash<QString,RideMetric*> &,
const MainWindow *main) {
const MainWindow *) {
// unconst naughty boy
RideFile *uride = const_cast<RideFile*>(ride);
if (!ride->dataPoints().isEmpty()) {
weight = getWeight(main, ride);
weight = uride->getWeight();
//weight = ride->getTag("Weight", appsettings->cvalue(GC_WEIGHT, "75.0").toString()).toDouble(); // default to 75kg
QList<BestIntervalDialog::BestInterval> results;
BestIntervalDialog::findBests(ride, secs, 1, results);