Speedup for charts by caching aggregated sleep amounts and steps for maximum 32 days

master
Andreas Shimokawa 2017-02-26 00:40:50 +01:00
parent aac9827e63
commit 8b39ef3a52
7 changed files with 62 additions and 24 deletions

View File

@ -1,5 +1,6 @@
package nodomain.freeyourgadget.gadgetbridge.activities.charts; package nodomain.freeyourgadget.gadgetbridge.activities.charts;
import android.app.Activity;
import android.graphics.Color; import android.graphics.Color;
import android.os.Bundle; import android.os.Bundle;
import android.view.LayoutInflater; import android.view.LayoutInflater;
@ -31,7 +32,9 @@ import java.util.Locale;
import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler; import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityAmounts;
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample; import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
import nodomain.freeyourgadget.gadgetbridge.util.LimitedQueue;
public abstract class AbstractWeekChartFragment extends AbstractChartFragment { public abstract class AbstractWeekChartFragment extends AbstractChartFragment {
@ -75,16 +78,15 @@ public abstract class AbstractWeekChartFragment extends AbstractChartFragment {
} }
private DefaultChartsData<BarData> refreshWeekBeforeData(DBHandler db, BarChart barChart, Calendar day, GBDevice device) { private DefaultChartsData<BarData> refreshWeekBeforeData(DBHandler db, BarChart barChart, Calendar day, GBDevice device) {
ActivityAnalysis analysis = new ActivityAnalysis();
day = (Calendar) day.clone(); // do not modify the caller's argument day = (Calendar) day.clone(); // do not modify the caller's argument
day.add(Calendar.DATE, -7); day.add(Calendar.DATE, -7);
List<BarEntry> entries = new ArrayList<>(); List<BarEntry> entries = new ArrayList<>();
ArrayList<String> labels = new ArrayList<String>(); ArrayList<String> labels = new ArrayList<String>();
for (int counter = 0; counter < 7; counter++) { for (int counter = 0; counter < 7; counter++) {
entries.add(new BarEntry(counter, getTotalForSamples(getSamplesOfDay(db, day, device)))); ActivityAmounts amounts = getActivityAmountsForDay(db, day, device);
entries.add(new BarEntry(counter, getTotalForActivityAmounts(amounts)));
labels.add(day.getDisplayName(Calendar.DAY_OF_WEEK, Calendar.SHORT, mLocale)); labels.add(day.getDisplayName(Calendar.DAY_OF_WEEK, Calendar.SHORT, mLocale));
day.add(Calendar.DATE, 1); day.add(Calendar.DATE, 1);
} }
@ -103,10 +105,9 @@ public abstract class AbstractWeekChartFragment extends AbstractChartFragment {
return new DefaultChartsData(barData, new PreformattedXIndexLabelFormatter(labels)); return new DefaultChartsData(barData, new PreformattedXIndexLabelFormatter(labels));
} }
private DayData refreshDayPie(DBHandler db, Calendar day, GBDevice device) { private DayData refreshDayPie(DBHandler db, Calendar day, GBDevice device) {
ActivityAmounts amounts = getActivityAmountsForDay(db, day, device);
int totalValue = getTotalForSamples(getSamplesOfDay(db, day, device)); int totalValue = getTotalForActivityAmounts(amounts);
PieData data = new PieData(); PieData data = new PieData();
List<PieEntry> entries = new ArrayList<>(); List<PieEntry> entries = new ArrayList<>();
@ -261,12 +262,33 @@ public abstract class AbstractWeekChartFragment extends AbstractChartFragment {
} }
} }
private ActivityAmounts getActivityAmountsForDay(DBHandler db, Calendar day, GBDevice device) {
LimitedQueue activityAmountCache = null;
ActivityAmounts amounts = null;
Activity activity = getActivity();
if (activity != null) {
activityAmountCache = ((ChartsActivity) activity).mActivityAmountCache;
amounts = (ActivityAmounts) (activityAmountCache.lookup(day.hashCode()));
}
if (amounts == null) {
ActivityAnalysis analysis = new ActivityAnalysis();
amounts = analysis.calculateActivityAmounts(getSamplesOfDay(db, day, device));
if (activityAmountCache != null) {
activityAmountCache.add(day.hashCode(), amounts);
}
}
return amounts;
}
abstract int getGoal(); abstract int getGoal();
abstract int getTotalForSamples(List<? extends ActivitySample> activitySamples); abstract int getTotalForActivityAmounts(ActivityAmounts activityAmounts);
abstract IValueFormatter getFormatter(); abstract IValueFormatter getFormatter();
abstract Integer getMainColor(); abstract Integer getMainColor();
} }

View File

@ -34,6 +34,11 @@ class ActivityAnalysis {
break; break;
} }
int steps = sample.getSteps();
if (steps > 0) {
amount.addSteps(sample.getSteps());
}
if (previousSample != null) { if (previousSample != null) {
long timeDifference = sample.getTimestamp() - previousSample.getTimestamp(); long timeDifference = sample.getTimestamp() - previousSample.getTimestamp();
if (previousSample.getRawKind() == sample.getRawKind()) { if (previousSample.getRawKind() == sample.getRawKind()) {

View File

@ -37,6 +37,7 @@ import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils; import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils;
import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper; import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper;
import nodomain.freeyourgadget.gadgetbridge.util.GB; import nodomain.freeyourgadget.gadgetbridge.util.GB;
import nodomain.freeyourgadget.gadgetbridge.util.LimitedQueue;
public class ChartsActivity extends AbstractGBFragmentActivity implements ChartsHost { public class ChartsActivity extends AbstractGBFragmentActivity implements ChartsHost {
@ -52,6 +53,8 @@ public class ChartsActivity extends AbstractGBFragmentActivity implements Charts
private PagerTabStrip mPagerTabStrip; private PagerTabStrip mPagerTabStrip;
private ViewPager viewPager; private ViewPager viewPager;
LimitedQueue mActivityAmountCache = new LimitedQueue(32);
private static class ShowDurationDialog extends Dialog { private static class ShowDurationDialog extends Dialog {
private final String mDuration; private final String mDuration;
private TextView durationLabel; private TextView durationLabel;

View File

@ -4,14 +4,12 @@ import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.formatter.IValueFormatter; import com.github.mikephil.charting.formatter.IValueFormatter;
import com.github.mikephil.charting.utils.ViewPortHandler; import com.github.mikephil.charting.utils.ViewPortHandler;
import java.util.List;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityAmount; import nodomain.freeyourgadget.gadgetbridge.model.ActivityAmount;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityAmounts; import nodomain.freeyourgadget.gadgetbridge.model.ActivityAmounts;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind; import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils; import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils;
public class WeekSleepChartFragment extends AbstractWeekChartFragment { public class WeekSleepChartFragment extends AbstractWeekChartFragment {
@ -26,11 +24,9 @@ public class WeekSleepChartFragment extends AbstractWeekChartFragment {
} }
@Override @Override
int getTotalForSamples(List<? extends ActivitySample> activitySamples) { int getTotalForActivityAmounts(ActivityAmounts activityAmounts) {
ActivityAnalysis analysis = new ActivityAnalysis();
ActivityAmounts amounts = analysis.calculateActivityAmounts(activitySamples);
long totalSeconds = 0; long totalSeconds = 0;
for (ActivityAmount amount : amounts.getAmounts()) { for (ActivityAmount amount : activityAmounts.getAmounts()) {
if ((amount.getActivityKind() & ActivityKind.TYPE_SLEEP) != 0) { if ((amount.getActivityKind() & ActivityKind.TYPE_SLEEP) != 0) {
totalSeconds += amount.getTotalSeconds(); totalSeconds += amount.getTotalSeconds();
} }

View File

@ -2,12 +2,11 @@ package nodomain.freeyourgadget.gadgetbridge.activities.charts;
import com.github.mikephil.charting.formatter.IValueFormatter; import com.github.mikephil.charting.formatter.IValueFormatter;
import java.util.List;
import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandCoordinator;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample; import nodomain.freeyourgadget.gadgetbridge.model.ActivityAmount;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityAmounts;
public class WeekStepsChartFragment extends AbstractWeekChartFragment { public class WeekStepsChartFragment extends AbstractWeekChartFragment {
@Override @Override
@ -25,9 +24,13 @@ public class WeekStepsChartFragment extends AbstractWeekChartFragment {
} }
@Override @Override
int getTotalForSamples(List<? extends ActivitySample> activitySamples) { int getTotalForActivityAmounts(ActivityAmounts activityAmounts) {
ActivityAnalysis analysis = new ActivityAnalysis(); int totalSteps = 0;
return analysis.calculateTotalSteps(activitySamples); for (ActivityAmount amount : activityAmounts.getAmounts()) {
totalSteps += amount.getTotalSteps();
amount.getTotalSteps();
}
return totalSteps;
} }
@Override @Override

View File

@ -8,6 +8,7 @@ public class ActivityAmount {
private final int activityKind; private final int activityKind;
private short percent; private short percent;
private long totalSeconds; private long totalSeconds;
private long totalSteps;
public ActivityAmount(int activityKind) { public ActivityAmount(int activityKind) {
this.activityKind = activityKind; this.activityKind = activityKind;
@ -17,10 +18,18 @@ public class ActivityAmount {
totalSeconds += seconds; totalSeconds += seconds;
} }
public void addSteps(long steps) {
totalSteps += steps;
}
public long getTotalSeconds() { public long getTotalSeconds() {
return totalSeconds; return totalSeconds;
} }
public long getTotalSteps() {
return totalSteps;
}
public int getActivityKind() { public int getActivityKind() {
return activityKind; return activityKind;
} }

View File

@ -13,14 +13,14 @@ public class LimitedQueue {
this.limit = limit; this.limit = limit;
} }
public void add(int id, Object obj) { synchronized public void add(int id, Object obj) {
if (list.size() > limit - 1) { if (list.size() > limit - 1) {
list.removeFirst(); list.removeFirst();
} }
list.add(new Pair<>(id, obj)); list.add(new Pair<>(id, obj));
} }
public void remove(int id) { synchronized public void remove(int id) {
for (Iterator<Pair> iter = list.iterator(); iter.hasNext(); ) { for (Iterator<Pair> iter = list.iterator(); iter.hasNext(); ) {
Pair pair = iter.next(); Pair pair = iter.next();
if ((Integer) pair.first == id) { if ((Integer) pair.first == id) {
@ -29,7 +29,7 @@ public class LimitedQueue {
} }
} }
public Object lookup(int id) { synchronized public Object lookup(int id) {
for (Pair entry : list) { for (Pair entry : list) {
if (id == (Integer) entry.first) { if (id == (Integer) entry.first) {
return entry.second; return entry.second;