From b06592eae0aa642753073c8c8af192692f4c8ff1 Mon Sep 17 00:00:00 2001 From: david-allison-1 <62114487+david-allison-1@users.noreply.github.com> Date: Tue, 24 Mar 2020 19:27:03 +0000 Subject: [PATCH] Calculate scheduler limits for sync using AnkiWeb limit Fixes #5666 - Sync Failure on Large Dynamic Decks We modified `mReportLimit` in #5326 to allow a user to see how many cards they had if there were more than 1000 in a queue. This had an impact on calculating the number of cards in the current deck, which is required for a sync to ensure that the server and client are consistent. This caused an inconsistency (as we calculate the proper value), and this meant that a full sync needed to occur if a dynamic deck with over 1000 cards in a queue was selected. This fixes it by using a new scheduler with the correct `mReportLimit` for calculating the number of cards in the selected deck --- .../main/java/com/ichi2/libanki/Collection.java | 13 +++++++++++++ .../src/main/java/com/ichi2/libanki/Sched.java | 14 ++++++++++++++ .../src/main/java/com/ichi2/libanki/SchedV2.java | 15 +++++++++++++++ .../main/java/com/ichi2/libanki/sync/Syncer.java | 10 +++++++++- 4 files changed, 51 insertions(+), 1 deletion(-) diff --git a/AnkiDroid/src/main/java/com/ichi2/libanki/Collection.java b/AnkiDroid/src/main/java/com/ichi2/libanki/Collection.java index f18b2dd2431a..c4f4438ff8b3 100644 --- a/AnkiDroid/src/main/java/com/ichi2/libanki/Collection.java +++ b/AnkiDroid/src/main/java/com/ichi2/libanki/Collection.java @@ -2124,4 +2124,17 @@ public Context getContext() { return mContext; } + /** Not in libAnki */ + + //This duplicates _loadScheduler (but returns the value and sets the report limit). + public Sched createScheduler(int reportLimit) { + int ver = schedVer(); + if (ver == 1) { + mSched = new Sched(this); + } else if (ver == 2) { + mSched = new SchedV2(this); + } + mSched.setReportLimit(reportLimit); + return mSched; + } } diff --git a/AnkiDroid/src/main/java/com/ichi2/libanki/Sched.java b/AnkiDroid/src/main/java/com/ichi2/libanki/Sched.java index b08300c2013a..c088ebb1c002 100644 --- a/AnkiDroid/src/main/java/com/ichi2/libanki/Sched.java +++ b/AnkiDroid/src/main/java/com/ichi2/libanki/Sched.java @@ -2486,6 +2486,20 @@ public boolean leechActionSuspend(Card card) { } } + /** not in libAnki. Added due to #5666: inconsistent selected deck card counts on sync */ + public int[] recalculateCounts() { + _resetLrnCount(); + _resetNewCount(); + _resetRevCount(); + return new int[] { mNewCount, mLrnCount, mRevCount }; + } + + public void setReportLimit(int reportLimit) { + this.mReportLimit = reportLimit; + } + + /** End #5666 */ + public void setContext(WeakReference contextReference) { mContextReference = contextReference; diff --git a/AnkiDroid/src/main/java/com/ichi2/libanki/SchedV2.java b/AnkiDroid/src/main/java/com/ichi2/libanki/SchedV2.java index 060ed7acf7a6..392c10fd69e3 100644 --- a/AnkiDroid/src/main/java/com/ichi2/libanki/SchedV2.java +++ b/AnkiDroid/src/main/java/com/ichi2/libanki/SchedV2.java @@ -2744,4 +2744,19 @@ public void setContext(WeakReference contextReference) { mContextReference = contextReference; } + /** not in libAnki. Added due to #5666: inconsistent selected deck card counts on sync */ + @Override + public int[] recalculateCounts() { + _resetLrnCount(); + _resetNewCount(); + _resetRevCount(); + return new int[] { mNewCount, mLrnCount, mRevCount }; + } + + @Override + public void setReportLimit(int reportLimit) { + this.mReportLimit = reportLimit; + } + + /** End #5666 */ } diff --git a/AnkiDroid/src/main/java/com/ichi2/libanki/sync/Syncer.java b/AnkiDroid/src/main/java/com/ichi2/libanki/sync/Syncer.java index f4195ceb9026..12c2171ab085 100644 --- a/AnkiDroid/src/main/java/com/ichi2/libanki/sync/Syncer.java +++ b/AnkiDroid/src/main/java/com/ichi2/libanki/sync/Syncer.java @@ -27,6 +27,7 @@ import com.ichi2.async.Connection; import com.ichi2.libanki.Collection; import com.ichi2.libanki.Consts; +import com.ichi2.libanki.Sched; import com.ichi2.libanki.Utils; import org.json.JSONArray; @@ -57,6 +58,9 @@ public class Syncer { public static final int TYPE_STRING = 3; public static final int TYPE_BLOB = 4; + /** The libAnki value of `sched.mReportLimit` */ + private static final int SYNC_SCHEDULER_REPORT_LIMIT = 1000; + private Collection mCol; private HttpSyncer mServer; private long mRMod; @@ -377,7 +381,11 @@ public JSONObject sanityCheck() { // return summary of deck JSONArray ja = new JSONArray(); JSONArray sa = new JSONArray(); - for (int c : mCol.getSched().counts()) { + + //#5666 - not in libAnki + //We modified mReportLimit inside the scheduler, and this causes issues syncing dynamic decks. + Sched syncScheduler = mCol.createScheduler(SYNC_SCHEDULER_REPORT_LIMIT); + for (int c : syncScheduler.recalculateCounts()) { sa.put(c); } ja.put(sa);