diff --git a/android/uhabits-android/src/androidTest/java/org/isoron/uhabits/performance/PerformanceTest.java b/android/uhabits-android/src/androidTest/java/org/isoron/uhabits/performance/PerformanceTest.java index 0dba9879f..912234c0b 100644 --- a/android/uhabits-android/src/androidTest/java/org/isoron/uhabits/performance/PerformanceTest.java +++ b/android/uhabits-android/src/androidTest/java/org/isoron/uhabits/performance/PerformanceTest.java @@ -19,16 +19,19 @@ package org.isoron.uhabits.performance; +import androidx.test.ext.junit.runners.*; import androidx.test.filters.*; -import androidx.test.runner.*; - -import androidx.test.ext.junit.runners.AndroidJUnit4; import org.isoron.uhabits.*; +import org.isoron.uhabits.core.commands.*; +import org.isoron.uhabits.core.database.*; import org.isoron.uhabits.core.models.*; +import org.isoron.uhabits.core.models.sqlite.*; import org.junit.*; import org.junit.runner.*; +import static org.isoron.uhabits.core.models.Timestamp.*; + @RunWith(AndroidJUnit4.class) @MediumTest public class PerformanceTest extends BaseAndroidTest @@ -42,7 +45,7 @@ public class PerformanceTest extends BaseAndroidTest habit = fixtures.createLongHabit(); } - @Test(timeout = 4000) + @Test(timeout = 5000) public void testRepeatedGetTodayValue() { for (int i = 0; i < 100000; i++) @@ -52,4 +55,32 @@ public class PerformanceTest extends BaseAndroidTest } } + @Test(timeout = 1000) + public void benchmarkCreateHabitCommand() + { + Database db = ((SQLModelFactory) modelFactory).db; + db.beginTransaction(); + for (int i = 0; i < 1_000; i++) + { + Habit model = modelFactory.buildHabit(); + new CreateHabitCommand(modelFactory, habitList, model).execute(); + } + db.setTransactionSuccessful(); + db.endTransaction(); + } + + @Test(timeout = 5000) + public void benchmarkCreateRepetitionCommand() + { + Database db = ((SQLModelFactory) modelFactory).db; + db.beginTransaction(); + Habit habit = fixtures.createEmptyHabit(); + for (int i = 0; i < 5_000; i++) + { + Timestamp timestamp = new Timestamp(i * DAY_LENGTH); + new CreateRepetitionCommand(habitList, habit, timestamp, 1).execute(); + } + db.setTransactionSuccessful(); + db.endTransaction(); + } } diff --git a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/commands/CreateRepetitionCommand.java b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/commands/CreateRepetitionCommand.java index 33c0148da..2f651ae49 100644 --- a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/commands/CreateRepetitionCommand.java +++ b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/commands/CreateRepetitionCommand.java @@ -60,6 +60,7 @@ public class CreateRepetitionCommand extends Command RepetitionList reps = habit.getRepetitions(); previousValue = reps.getValue(timestamp); reps.setValue(timestamp, value); + habitList.resort(); } @NonNull diff --git a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/models/HabitList.java b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/models/HabitList.java index 47b3a1cef..50f8c10ac 100644 --- a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/models/HabitList.java +++ b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/models/HabitList.java @@ -260,7 +260,7 @@ public abstract class HabitList implements Iterable csv.close(); } - + public abstract void resort(); public enum Order { diff --git a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/models/memory/MemoryHabitList.java b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/models/memory/MemoryHabitList.java index 503d5278d..26eb9d6a1 100644 --- a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/models/memory/MemoryHabitList.java +++ b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/models/memory/MemoryHabitList.java @@ -79,8 +79,6 @@ public class MemoryHabitList extends HabitList if (id == null) habit.setId((long) list.size()); list.addLast(habit); resort(); - - getObservable().notifyListeners(); } @Override @@ -133,7 +131,6 @@ public class MemoryHabitList extends HabitList this.primaryOrder = order; this.comparator = getComposedComparatorByOrder(this.primaryOrder, this.secondaryOrder); resort(); - getObservable().notifyListeners(); } @Override @@ -142,7 +139,6 @@ public class MemoryHabitList extends HabitList this.secondaryOrder = order; this.comparator = getComposedComparatorByOrder(this.primaryOrder, this.secondaryOrder); resort(); - getObservable().notifyListeners(); } private Comparator getComposedComparatorByOrder(Order firstOrder, Order secondOrder) @@ -265,7 +261,6 @@ public class MemoryHabitList extends HabitList public synchronized void update(List habits) { resort(); - getObservable().notifyListeners(); } private void throwIfHasParent() @@ -284,8 +279,9 @@ public class MemoryHabitList extends HabitList resort(); } - private synchronized void resort() + public synchronized void resort() { if (comparator != null) Collections.sort(list, comparator); + getObservable().notifyListeners(); } } diff --git a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/models/sqlite/SQLiteHabitList.java b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/models/sqlite/SQLiteHabitList.java index f940c436a..86c764bc7 100644 --- a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/models/sqlite/SQLiteHabitList.java +++ b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/models/sqlite/SQLiteHabitList.java @@ -66,12 +66,20 @@ public class SQLiteHabitList extends HabitList list.removeAll(); List records = repository.findAll("order by position"); + + int expectedPosition = 0; + boolean shouldRebuildOrder = false; for (HabitRecord rec : records) { + if (rec.position != expectedPosition) shouldRebuildOrder = true; + expectedPosition++; + Habit h = modelFactory.buildHabit(); rec.copyTo(h); list.add(h); } + + if(shouldRebuildOrder) rebuildOrder(); } @Override @@ -84,7 +92,6 @@ public class SQLiteHabitList extends HabitList record.copyFrom(habit); repository.save(record); habit.id = record.id; - rebuildOrder(); list.add(habit); getObservable().notifyListeners(); @@ -166,11 +173,17 @@ public class SQLiteHabitList extends HabitList private synchronized void rebuildOrder() { List records = repository.findAll("order by position"); - repository.executeAsTransaction(() -> { + repository.executeAsTransaction(() -> + { int pos = 0; - for (HabitRecord r : records) { - r.position = pos++; - repository.save(r); + for (HabitRecord r : records) + { + if (r.position != pos) + { + r.position = pos; + repository.save(r); + } + pos++; } }); } @@ -179,6 +192,9 @@ public class SQLiteHabitList extends HabitList public synchronized void remove(@NonNull Habit habit) { loadRecords(); + + reorder(habit, list.getByPosition(size() - 1)); + list.remove(habit); HabitRecord record = repository.find(habit.getId()); @@ -189,7 +205,6 @@ public class SQLiteHabitList extends HabitList repository.remove(record); }); - rebuildOrder(); getObservable().notifyListeners(); } @@ -267,6 +282,13 @@ public class SQLiteHabitList extends HabitList getObservable().notifyListeners(); } + @Override + public void resort() + { + list.resort(); + getObservable().notifyListeners(); + } + public synchronized void reload() { loaded = false;