Replace invalidateNewerThan by recompute; add newComputedEntries

pull/699/head
Alinson S. Xavier 5 years ago
parent f6754ff180
commit 2e19fee83c

@ -49,7 +49,7 @@ public class TargetWidgetTest extends BaseViewTest
habit = fixtures.createLongNumericalHabit(); habit = fixtures.createLongNumericalHabit();
habit.setColor(new PaletteColor(11)); habit.setColor(new PaletteColor(11));
habit.setFrequency(Frequency.WEEKLY); habit.setFrequency(Frequency.WEEKLY);
habit.invalidateNewerThan(Timestamp.ZERO); habit.recompute();
TargetWidget widget = new TargetWidget(targetContext, 0, habit); TargetWidget widget = new TargetWidget(targetContext, 0, habit);
view = convertToView(widget, 400, 400); view = convertToView(widget, 400, 400);
} }

@ -54,7 +54,7 @@ public class CreateRepetitionCommand implements Command
{ {
Entries checks = habit.getOriginalEntries(); Entries checks = habit.getOriginalEntries();
checks.add(new Entry(timestamp, value)); checks.add(new Entry(timestamp, value));
habit.invalidateNewerThan(Timestamp.ZERO); habit.recompute();
habitList.resort(); habitList.resort();
} }

@ -83,7 +83,7 @@ public class EditHabitCommand implements Command
habit.getObservable().notifyListeners(); habit.getObservable().notifyListeners();
if (hasFrequencyChanged || hasTargetChanged) if (hasFrequencyChanged || hasTargetChanged)
habit.invalidateNewerThan(Timestamp.ZERO); habit.recompute();
} }
} }

@ -113,13 +113,13 @@ open class Entries {
* For boolean habits, this function creates additional entries (with value YES_AUTO) according * For boolean habits, this function creates additional entries (with value YES_AUTO) according
* to the frequency of the habit. For numerical habits, this function simply copies all entries. * to the frequency of the habit. For numerical habits, this function simply copies all entries.
*/ */
open fun computeFrom( open fun recomputeFrom(
other: Entries, originalEntries: Entries,
frequency: Frequency, frequency: Frequency,
isNumerical: Boolean, isNumerical: Boolean,
) { ) {
clear() clear()
val original = other.getKnown() val original = originalEntries.getKnown()
if (isNumerical) { if (isNumerical) {
original.forEach { add(it) } original.forEach { add(it) }
} else { } else {

@ -320,9 +320,8 @@ public class EntryList
* than a given timestamp. These checkmarks will be recomputed at the next * than a given timestamp. These checkmarks will be recomputed at the next
* time they are queried. * time they are queried.
* *
* @param timestamp the timestamp
*/ */
public void invalidateNewerThan(Timestamp timestamp) public void recompute()
{ {
list.clear(); list.clear();
} }
@ -364,7 +363,7 @@ public class EntryList
Entry newest = getNewestComputed(); Entry newest = getNewestComputed();
if (newest != null && newest.getTimestamp().equals(today)) return; if (newest != null && newest.getTimestamp().equals(today)) return;
invalidateNewerThan(Timestamp.ZERO); recompute();
List<Entry> entries = habit.getOriginalEntries().getKnown(); List<Entry> entries = habit.getOriginalEntries().getKnown();
if(entries.isEmpty()) return; if(entries.isEmpty()) return;

@ -34,6 +34,7 @@ data class Habit(
var unit: String = "", var unit: String = "",
var uuid: String? = null, var uuid: String? = null,
val computedEntries: EntryList, val computedEntries: EntryList,
val newComputedEntries: Entries,
val originalEntries: Entries, val originalEntries: Entries,
val scores: ScoreList, val scores: ScoreList,
val streaks: StreakList, val streaks: StreakList,
@ -50,10 +51,15 @@ data class Habit(
fun isCompletedToday(): Boolean = computedEntries.isCompletedToday fun isCompletedToday(): Boolean = computedEntries.isCompletedToday
fun invalidateNewerThan(timestamp: Timestamp?) { fun recompute() {
scores.invalidateNewerThan(timestamp) scores.recompute()
computedEntries.invalidateNewerThan(timestamp) computedEntries.recompute()
streaks.invalidateNewerThan(timestamp) streaks.recompute()
newComputedEntries.recomputeFrom(
originalEntries = originalEntries,
frequency = frequency,
isNumerical = isNumerical,
)
} }
fun copyFrom(other: Habit) { fun copyFrom(other: Habit) {

@ -178,9 +178,9 @@ public abstract class HabitList implements Iterable<Habit>
{ {
for (Habit h : this) for (Habit h : this)
{ {
h.getComputedEntries().invalidateNewerThan(Timestamp.ZERO); h.getComputedEntries().recompute();
h.getStreaks().invalidateNewerThan(Timestamp.ZERO); h.getStreaks().recompute();
h.getScores().invalidateNewerThan(Timestamp.ZERO); h.getScores().recompute();
} }
} }

@ -36,13 +36,15 @@ interface ModelFactory {
scores = scores, scores = scores,
streaks = streaks, streaks = streaks,
originalEntries = buildOriginalEntries(), originalEntries = buildOriginalEntries(),
newComputedEntries = buildNewComputedEntries(),
) )
computedEntries.setHabit(habit) computedEntries.setHabit(habit)
scores.setHabit(habit) scores.setHabit(habit)
streaks.setHabit(habit) streaks.setHabit(habit)
habit.recompute()
return habit return habit
} }
fun buildNewComputedEntries(): Entries
fun buildOriginalEntries(): Entries fun buildOriginalEntries(): Entries
fun buildEntryList(): EntryList fun buildEntryList(): EntryList
fun buildHabitList(): HabitList fun buildHabitList(): HabitList

@ -131,14 +131,7 @@ public abstract class ScoreList implements Iterable<Score>
return scores; return scores;
} }
/** public abstract void recompute();
* 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.
*
* @param timestamp the oldest timestamp that should be invalidated
*/
public abstract void invalidateNewerThan(Timestamp timestamp);
@Override @Override
public Iterator<Score> iterator() public Iterator<Score> iterator()

@ -62,7 +62,7 @@ public abstract class StreakList
return observable; return observable;
} }
public abstract void invalidateNewerThan(Timestamp timestamp); public abstract void recompute();
public synchronized void rebuild() public synchronized void rebuild()
{ {

@ -21,6 +21,7 @@ package org.isoron.uhabits.core.models.memory
import org.isoron.uhabits.core.models.* import org.isoron.uhabits.core.models.*
class MemoryModelFactory : ModelFactory { class MemoryModelFactory : ModelFactory {
override fun buildNewComputedEntries() = Entries()
override fun buildOriginalEntries() = Entries() override fun buildOriginalEntries() = Entries()
override fun buildEntryList() = EntryList() override fun buildEntryList() = EntryList()
override fun buildHabitList() = MemoryHabitList() override fun buildHabitList() = MemoryHabitList()

@ -68,7 +68,7 @@ public class MemoryScoreList extends ScoreList
} }
@Override @Override
public void invalidateNewerThan(Timestamp timestamp) public void recompute()
{ {
list.clear(); list.clear();
getObservable().notifyListeners(); getObservable().notifyListeners();

@ -42,7 +42,7 @@ public class MemoryStreakList extends StreakList
} }
@Override @Override
public void invalidateNewerThan(Timestamp timestamp) public void recompute()
{ {
list.clear(); list.clear();
observable.notifyListeners(); observable.notifyListeners();

@ -34,6 +34,7 @@ class SQLModelFactory
val database: Database, val database: Database,
) : ModelFactory { ) : ModelFactory {
override fun buildOriginalEntries() = SQLiteEntries(database) override fun buildOriginalEntries() = SQLiteEntries(database)
override fun buildNewComputedEntries() = Entries()
override fun buildEntryList() = EntryList() override fun buildEntryList() = EntryList()
override fun buildHabitList() = SQLiteHabitList(this) override fun buildHabitList() = SQLiteHabitList(this)
override fun buildScoreList() = MemoryScoreList() override fun buildScoreList() = MemoryScoreList()

@ -76,7 +76,7 @@ class SQLiteEntries(database: Database) : Entries() {
return super.groupBy(field, firstWeekday, isNumerical) return super.groupBy(field, firstWeekday, isNumerical)
} }
override fun computeFrom(other: Entries, frequency: Frequency, isNumerical: Boolean) { override fun recomputeFrom(originalEntries: Entries, frequency: Frequency, isNumerical: Boolean) {
throw UnsupportedOperationException() throw UnsupportedOperationException()
} }

@ -67,7 +67,7 @@ class ShowHabitMenuBehavior(
if (habit.isNumerical) value = (1000 + 250 * random.nextGaussian() * strength / 100).toInt() * 1000 if (habit.isNumerical) value = (1000 + 250 * random.nextGaussian() * strength / 100).toInt() * 1000
habit.originalEntries.add(Entry(DateUtils.getToday().minus(i), value)) habit.originalEntries.add(Entry(DateUtils.getToday().minus(i), value))
} }
habit.invalidateNewerThan(Timestamp.ZERO) habit.recompute()
screen.refresh() screen.refresh()
} }

@ -95,7 +95,7 @@ class EntriesTest {
original.add(Entry(today.minus(10), YES_MANUAL)) original.add(Entry(today.minus(10), YES_MANUAL))
val computed = Entries() val computed = Entries()
computed.computeFrom(original, Frequency(1, 3), isNumerical = false) computed.recomputeFrom(original, Frequency(1, 3), isNumerical = false)
val expected = listOf( val expected = listOf(
Entry(today.minus(2), YES_AUTO), Entry(today.minus(2), YES_AUTO),
@ -111,7 +111,7 @@ class EntriesTest {
assertEquals(expected, computed.getKnown()) assertEquals(expected, computed.getKnown())
// Second call should replace all previously added entries // Second call should replace all previously added entries
computed.computeFrom(Entries(), Frequency(1, 3), isNumerical = false) computed.recomputeFrom(Entries(), Frequency(1, 3), isNumerical = false)
assertEquals(listOf(), computed.getKnown()) assertEquals(listOf(), computed.getKnown())
} }
@ -126,7 +126,7 @@ class EntriesTest {
original.add(Entry(today.minus(10), 300)) original.add(Entry(today.minus(10), 300))
val computed = Entries() val computed = Entries()
computed.computeFrom(original, Frequency.DAILY, isNumerical = true) computed.recomputeFrom(original, Frequency.DAILY, isNumerical = true)
val expected = listOf( val expected = listOf(
Entry(today.minus(4), 100), Entry(today.minus(4), 100),

@ -87,28 +87,28 @@ public class HabitTest extends BaseUnitTest
assertFalse(h.isCompletedToday()); assertFalse(h.isCompletedToday());
h.getOriginalEntries().add(new Entry(getToday(), 200_000)); h.getOriginalEntries().add(new Entry(getToday(), 200_000));
h.invalidateNewerThan(Timestamp.ZERO); h.recompute();
assertTrue(h.isCompletedToday()); assertTrue(h.isCompletedToday());
h.getOriginalEntries().add(new Entry(getToday(), 100_000)); h.getOriginalEntries().add(new Entry(getToday(), 100_000));
h.invalidateNewerThan(Timestamp.ZERO); h.recompute();
assertTrue(h.isCompletedToday()); assertTrue(h.isCompletedToday());
h.getOriginalEntries().add(new Entry(getToday(), 50_000)); h.getOriginalEntries().add(new Entry(getToday(), 50_000));
h.invalidateNewerThan(Timestamp.ZERO); h.recompute();
assertFalse(h.isCompletedToday()); assertFalse(h.isCompletedToday());
h.setTargetType(Habit.AT_MOST); h.setTargetType(Habit.AT_MOST);
h.getOriginalEntries().add(new Entry(getToday(), 200_000)); h.getOriginalEntries().add(new Entry(getToday(), 200_000));
h.invalidateNewerThan(Timestamp.ZERO); h.recompute();
assertFalse(h.isCompletedToday()); assertFalse(h.isCompletedToday());
h.getOriginalEntries().add(new Entry(getToday(), 100_000)); h.getOriginalEntries().add(new Entry(getToday(), 100_000));
h.invalidateNewerThan(Timestamp.ZERO); h.recompute();
assertTrue(h.isCompletedToday()); assertTrue(h.isCompletedToday());
h.getOriginalEntries().add(new Entry(getToday(), 50_000)); h.getOriginalEntries().add(new Entry(getToday(), 50_000));
h.invalidateNewerThan(Timestamp.ZERO); h.recompute();
assertTrue(h.isCompletedToday()); assertTrue(h.isCompletedToday());
} }

@ -219,7 +219,7 @@ public class ScoreListTest extends BaseUnitTest
// Missing 2 repetitions out of 4 per week, the score should converge to 50% // Missing 2 repetitions out of 4 per week, the score should converge to 50%
habit.setFrequency(new Frequency(4, 7)); habit.setFrequency(new Frequency(4, 7));
habit.invalidateNewerThan(Timestamp.ZERO); habit.recompute();
assertThat(habit.getScores().getTodayValue(), closeTo(0.5, E)); assertThat(habit.getScores().getTodayValue(), closeTo(0.5, E));
} }
@ -289,7 +289,7 @@ public class ScoreListTest extends BaseUnitTest
} }
@Test @Test
public void test_invalidateNewerThan() public void test_recompute()
{ {
assertThat(habit.getScores().getTodayValue(), closeTo(0.0, E)); assertThat(habit.getScores().getTodayValue(), closeTo(0.0, E));
@ -297,7 +297,7 @@ public class ScoreListTest extends BaseUnitTest
assertThat(habit.getScores().getTodayValue(), closeTo(0.101149, E)); assertThat(habit.getScores().getTodayValue(), closeTo(0.101149, E));
habit.setFrequency(new Frequency(1, 2)); habit.setFrequency(new Frequency(1, 2));
habit.getScores().invalidateNewerThan(new Timestamp(0)); habit.getScores().recompute();
assertThat(habit.getScores().getTodayValue(), closeTo(0.054816, E)); assertThat(habit.getScores().getTodayValue(), closeTo(0.054816, E));
} }
@ -339,7 +339,7 @@ public class ScoreListTest extends BaseUnitTest
for (int i = from; i < to; i++) for (int i = from; i < to; i++)
entries.add(new Entry(today.minus(i), YES_MANUAL)); entries.add(new Entry(today.minus(i), YES_MANUAL));
habit.invalidateNewerThan(Timestamp.ZERO); habit.recompute();
} }
private void check(ArrayList<Integer> values) private void check(ArrayList<Integer> values)

@ -69,7 +69,7 @@ public class StreakListTest extends BaseUnitTest
public void testFindBeginning_withLongHistory() public void testFindBeginning_withLongHistory()
{ {
streaks.rebuild(); streaks.rebuild();
streaks.invalidateNewerThan(new Timestamp(0)); streaks.recompute();
assertThat(streaks.findBeginning(), equalTo(today.minus(120))); assertThat(streaks.findBeginning(), equalTo(today.minus(120)));
} }
@ -111,7 +111,7 @@ public class StreakListTest extends BaseUnitTest
Streak s = streaks.getNewestComputed(); Streak s = streaks.getNewestComputed();
assertThat(s.getEnd(), equalTo(today)); assertThat(s.getEnd(), equalTo(today));
streaks.invalidateNewerThan(today.minus(8)); streaks.recompute();
verify(listener).onModelChange(); verify(listener).onModelChange();
s = streaks.getNewestComputed(); s = streaks.getNewestComputed();

Loading…
Cancel
Save