more synchronized access in treatments

This commit is contained in:
Milos Kozak 2018-03-25 17:33:03 +02:00
parent 51e0774021
commit f939994afa
5 changed files with 94 additions and 54 deletions

View file

@ -16,7 +16,15 @@ import info.nightscout.androidaps.interfaces.Interval;
public abstract class Intervals<T extends Interval> {
LongSparseArray<T> rawData = new LongSparseArray<T>(); // oldest at index 0
LongSparseArray<T> rawData; // oldest at index 0
public Intervals() {
rawData = new LongSparseArray<T>();
}
public Intervals(LongSparseArray<T> data) {
rawData = data;
}
public synchronized Intervals reset() {
rawData = new LongSparseArray<T>();
@ -27,8 +35,7 @@ public abstract class Intervals<T extends Interval> {
/**
* The List must be sorted by `T.start()` in ascending order
*
* */
*/
public synchronized void add(List<T> list) {
for (T interval : list) {
rawData.put(interval.start(), interval);
@ -37,7 +44,6 @@ public abstract class Intervals<T extends Interval> {
}
public synchronized List<T> getList() {
List<T> list = new ArrayList<>();
for (int i = 0; i < rawData.size(); i++)
@ -47,7 +53,7 @@ public abstract class Intervals<T extends Interval> {
public synchronized List<T> getReversedList() {
List<T> list = new ArrayList<>();
for (int i = rawData.size() -1; i>=0; i--)
for (int i = rawData.size() - 1; i >= 0; i--)
list.add(rawData.valueAt(i));
return list;
}
@ -86,5 +92,4 @@ public abstract class Intervals<T extends Interval> {
}
}

View file

@ -2,7 +2,9 @@ package info.nightscout.androidaps.data;
import android.support.annotation.Nullable;
import android.support.v4.util.LongSparseArray;
import info.nightscout.androidaps.db.TemporaryBasal;
import info.nightscout.androidaps.interfaces.Interval;
/**
@ -11,6 +13,18 @@ import info.nightscout.androidaps.interfaces.Interval;
public class NonOverlappingIntervals<T extends Interval> extends Intervals<T> {
public NonOverlappingIntervals() {
super();
}
public NonOverlappingIntervals(LongSparseArray<T> data) {
super(data);
}
public NonOverlappingIntervals (Intervals<T> other) {
rawData = other.rawData.clone();
}
protected synchronized void merge() {
for (int index = 0; index < rawData.size() - 1; index++) {
Interval i = rawData.valueAt(index);
@ -27,4 +41,5 @@ public class NonOverlappingIntervals<T extends Interval> extends Intervals<T> {
if (index >= 0) return rawData.valueAt(index);
return null;
}
}

View file

@ -22,7 +22,15 @@ import info.nightscout.utils.DateUtil;
public class ProfileIntervals<T extends Interval> {
private static Logger log = LoggerFactory.getLogger(ProfileIntervals.class);
private LongSparseArray<T> rawData = new LongSparseArray<>(); // oldest at index 0
private LongSparseArray<T> rawData; // oldest at index 0
public ProfileIntervals () {
rawData = new LongSparseArray<>();
}
public ProfileIntervals (ProfileIntervals<T> other) {
rawData = other.rawData.clone();
}
public synchronized ProfileIntervals reset() {
rawData = new LongSparseArray<>();

View file

@ -57,7 +57,7 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface {
private IobTotal lastTreatmentCalculation;
private IobTotal lastTempBasalsCalculation;
public static List<Treatment> treatments;
private final static ArrayList<Treatment> treatments = new ArrayList<>();
private final static Intervals<TemporaryBasal> tempBasals = new NonOverlappingIntervals<>();
private final static Intervals<ExtendedBolus> extendedBoluses = new NonOverlappingIntervals<>();
private final static Intervals<TempTarget> tempTargets = new OverlappingIntervals<>();
@ -146,8 +146,10 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface {
if (MainApp.getConfigBuilder() != null && MainApp.getConfigBuilder().getProfile() != null)
dia = MainApp.getConfigBuilder().getProfile().getDia();
long fromMills = (long) (System.currentTimeMillis() - 60 * 60 * 1000L * (24 + dia));
treatments = MainApp.getDbHelper().getTreatmentDataFromTime(fromMills, false);
synchronized (treatments) {
treatments.clear();
treatments.addAll(MainApp.getDbHelper().getTreatmentDataFromTime(fromMills, false));
}
}
private static void initializeTempBasalData() {
@ -202,22 +204,24 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface {
double dia = profile.getDia();
for (Integer pos = 0; pos < treatments.size(); pos++) {
Treatment t = treatments.get(pos);
if (!t.isValid) continue;
if (t.date > time) continue;
Iob tIOB = t.iobCalc(time, dia);
total.iob += tIOB.iobContrib;
total.activity += tIOB.activityContrib;
if (t.date > total.lastBolusTime)
total.lastBolusTime = t.date;
if (!t.isSMB) {
// instead of dividing the DIA that only worked on the bilinear curves,
// multiply the time the treatment is seen active.
long timeSinceTreatment = time - t.date;
long snoozeTime = t.date + (long) (timeSinceTreatment * SP.getDouble("openapsama_bolussnooze_dia_divisor", 2.0));
Iob bIOB = t.iobCalc(snoozeTime, dia);
total.bolussnooze += bIOB.iobContrib;
synchronized (treatments) {
for (Integer pos = 0; pos < treatments.size(); pos++) {
Treatment t = treatments.get(pos);
if (!t.isValid) continue;
if (t.date > time) continue;
Iob tIOB = t.iobCalc(time, dia);
total.iob += tIOB.iobContrib;
total.activity += tIOB.activityContrib;
if (t.date > total.lastBolusTime)
total.lastBolusTime = t.date;
if (!t.isSMB) {
// instead of dividing the DIA that only worked on the bilinear curves,
// multiply the time the treatment is seen active.
long timeSinceTreatment = time - t.date;
long snoozeTime = t.date + (long) (timeSinceTreatment * SP.getDouble("openapsama_bolussnooze_dia_divisor", 2.0));
Iob bIOB = t.iobCalc(snoozeTime, dia);
total.bolussnooze += bIOB.iobContrib;
}
}
}
@ -248,17 +252,19 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface {
long now = System.currentTimeMillis();
long dia_ago = now - (Double.valueOf(1.5d * profile.getDia() * 60 * 60 * 1000l)).longValue();
for (Treatment treatment : treatments) {
if (!treatment.isValid)
continue;
long t = treatment.date;
if (t > dia_ago && t <= now) {
if (treatment.carbs >= 1) {
result.carbs += treatment.carbs;
result.lastCarbTime = t;
}
if (treatment.insulin > 0 && treatment.mealBolus) {
result.boluses += treatment.insulin;
synchronized (treatments) {
for (Treatment treatment : treatments) {
if (!treatment.isValid)
continue;
long t = treatment.date;
if (t > dia_ago && t <= now) {
if (treatment.carbs >= 1) {
result.carbs += treatment.carbs;
result.lastCarbTime = t;
}
if (treatment.insulin > 0 && treatment.mealBolus) {
result.boluses += treatment.insulin;
}
}
}
}
@ -275,29 +281,35 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface {
@Override
public List<Treatment> getTreatmentsFromHistory() {
return treatments;
synchronized (treatments) {
return (List<Treatment>) treatments.clone();
}
}
@Override
public List<Treatment> getTreatments5MinBackFromHistory(long time) {
List<Treatment> in5minback = new ArrayList<>();
for (Integer pos = 0; pos < treatments.size(); pos++) {
Treatment t = treatments.get(pos);
if (!t.isValid)
continue;
if (t.date <= time && t.date > time - 5 * 60 * 1000 && t.carbs > 0)
in5minback.add(t);
synchronized (treatments) {
for (Integer pos = 0; pos < treatments.size(); pos++) {
Treatment t = treatments.get(pos);
if (!t.isValid)
continue;
if (t.date <= time && t.date > time - 5 * 60 * 1000 && t.carbs > 0)
in5minback.add(t);
}
return in5minback;
}
return in5minback;
}
@Override
public long getLastBolusTime() {
long now = System.currentTimeMillis();
long last = 0;
for (Treatment t : treatments) {
if (t.date > last && t.insulin > 0 && t.isValid && t.date <= now)
last = t.date;
synchronized (treatments) {
for (Treatment t : treatments) {
if (t.date > last && t.insulin > 0 && t.isValid && t.date <= now)
last = t.date;
}
}
log.debug("Last bolus time: " + new Date(last).toLocaleString());
return last;
@ -425,14 +437,14 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface {
@Override
public Intervals<ExtendedBolus> getExtendedBolusesFromHistory() {
synchronized (extendedBoluses) {
return extendedBoluses;
return new NonOverlappingIntervals<>(extendedBoluses);
}
}
@Override
public Intervals<TemporaryBasal> getTemporaryBasalsFromHistory() {
synchronized (tempBasals) {
return tempBasals;
return new NonOverlappingIntervals<>(tempBasals);
}
}
@ -514,7 +526,7 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface {
@Override
public Intervals<TempTarget> getTempTargetsFromHistory() {
synchronized (tempTargets) {
return tempTargets;
return new NonOverlappingIntervals<>(tempTargets);
}
}
@ -534,7 +546,7 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface {
@Override
public ProfileIntervals<ProfileSwitch> getProfileSwitchesFromHistory() {
synchronized (profiles) {
return profiles;
return new ProfileIntervals<>(profiles);
}
}

View file

@ -176,7 +176,7 @@ public class TreatmentsBolusFragment extends SubscriberFragment implements View.
llm = new LinearLayoutManager(view.getContext());
recyclerView.setLayoutManager(llm);
RecyclerViewAdapter adapter = new RecyclerViewAdapter(TreatmentsPlugin.treatments);
RecyclerViewAdapter adapter = new RecyclerViewAdapter(TreatmentsPlugin.getPlugin().getTreatmentsFromHistory());
recyclerView.setAdapter(adapter);
iobTotal = (TextView) view.findViewById(R.id.treatments_iobtotal);
@ -232,7 +232,7 @@ public class TreatmentsBolusFragment extends SubscriberFragment implements View.
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
recyclerView.swapAdapter(new RecyclerViewAdapter(TreatmentsPlugin.treatments), false);
recyclerView.swapAdapter(new RecyclerViewAdapter(TreatmentsPlugin.getPlugin().getTreatmentsFromHistory()), false);
if (TreatmentsPlugin.getPlugin().getLastCalculationTreatments() != null) {
iobTotal.setText(DecimalFormatter.to2Decimal(TreatmentsPlugin.getPlugin().getLastCalculationTreatments().iob) + " U");
activityTotal.setText(DecimalFormatter.to3Decimal(TreatmentsPlugin.getPlugin().getLastCalculationTreatments().activity) + " U");