From 3c927e009a38a70eea9f7c63f16c6677a8030169 Mon Sep 17 00:00:00 2001 From: Alinson Xavier Date: Fri, 1 Apr 2016 17:49:17 -0400 Subject: [PATCH] Improve performance of Score computation --- .../org/isoron/uhabits/models/ScoreList.java | 55 +++++++++---------- 1 file changed, 25 insertions(+), 30 deletions(-) diff --git a/app/src/main/java/org/isoron/uhabits/models/ScoreList.java b/app/src/main/java/org/isoron/uhabits/models/ScoreList.java index 36905ebd6..9146ed3c8 100644 --- a/app/src/main/java/org/isoron/uhabits/models/ScoreList.java +++ b/app/src/main/java/org/isoron/uhabits/models/ScoreList.java @@ -31,6 +31,7 @@ import com.activeandroid.query.From; import com.activeandroid.query.Select; import com.activeandroid.util.SQLiteUtils; +import org.isoron.uhabits.helpers.DatabaseHelper; import org.isoron.uhabits.helpers.DateHelper; import java.io.IOException; @@ -61,31 +62,6 @@ public class ScoreList .orderBy("timestamp desc"); } - /** - * Returns the most recent score already computed. If no score has been computed yet, returns - * null. - * - * @return newest score, or null if none exist - */ - @Nullable - protected Score findNewest() - { - return select().limit(1).executeSingle(); - } - - /** - * Returns the value of the most recent score that was already computed. If no score has been - * computed yet, returns zero. - * - * @return value of newest score, or zero if none exist - */ - protected int findNewestValue() - { - Score newest = findNewest(); - if(newest == null) return 0; - else return newest.score; - } - /** * Marks all scores that have timestamp equal to or newer than the given timestamp as invalid. * Any following getValue calls will trigger the scores to be recomputed. @@ -119,7 +95,7 @@ public class ScoreList * included. * * This function assumes that there are no gaps on the scores. That is, if the newest score has - * timestamp t, then every score with timestamp lower than t has already been computed. + * timestamp t, then every score with timestamp lower than t has already been computed. * * @param from timestamp of the beginning of the interval * @param to timestamp of the end of the time interval @@ -130,15 +106,14 @@ public class ScoreList final double freq = ((double) habit.freqNum) / habit.freqDen; int newestScoreValue = findNewestValue(); - Score newestScore = findNewest(); + long newestTimestamp = findNewestTimestamp(); - if(newestScore != null) - from = newestScore.timestamp + day; + if(newestTimestamp > 0) + from = newestTimestamp + day; final int checkmarkValues[] = habit.checkmarks.getValues(from, to); final long beginning = from; - int lastScore = newestScoreValue; int size = checkmarkValues.length; @@ -156,6 +131,26 @@ public class ScoreList insert(timestamps, values); } + /** + * Returns the value of the most recent score that was already computed. If no score has been + * computed yet, returns zero. + * + * @return value of newest score, or zero if none exist + */ + protected int findNewestValue() + { + String args[] = { habit.getId().toString() }; + String query = "select score from Score where habit = ? order by timestamp desc limit 1"; + return SQLiteUtils.intQuery(query, args); + } + + private long findNewestTimestamp() + { + String args[] = { habit.getId().toString() }; + String query = "select timestamp from Score where habit = ? order by timestamp desc limit 1"; + return DatabaseHelper.longQuery(query, args); + } + private void insert(long timestamps[], long values[]) { String query = "insert into Score(habit, timestamp, score) values (?,?,?)";