-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: TagsDialog crashes #16356
fix: TagsDialog crashes #16356
Conversation
This comment was marked as outdated.
This comment was marked as outdated.
For future Index: AnkiDroid/src/main/java/com/ichi2/anki/CardBrowser.kt
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/CardBrowser.kt b/AnkiDroid/src/main/java/com/ichi2/anki/CardBrowser.kt
--- a/AnkiDroid/src/main/java/com/ichi2/anki/CardBrowser.kt (revision 3c3f39d7de6756959acdd2b1fdc9c89473a257ff)
+++ b/AnkiDroid/src/main/java/com/ichi2/anki/CardBrowser.kt (date 1714909328656)
@@ -1295,14 +1295,21 @@
// TODO!! This is terribly slow on AnKing
// PERF: This MUST be combined with the above sequence - this becomes O(2n) on a
// database operation performed over 30k times
+ val potentialTags = allTags.toMutableSet()
val uncheckedTags = withCol {
selectedNoteIds
.asSequence() // reduce memory pressure
.flatMap { nid: NoteId ->
progress++
- val note = getNote(nid) // requires withCol
- val noteTags: List<String?> = note.tags
- allTags.filter { t: String? -> !noteTags.contains(t) }
+
+ // avoid DB access if no more tags to check
+ if (potentialTags.isEmpty()) return@flatMap emptyList<String>()
+
+ val noteTags = getNote(nid).tags.toSet() // requires withCol
+ val uncheckedTagsForNote = potentialTags - noteTags
+ // PERF: if we're returning these tags, we don't need to check them again
+ potentialTags -= uncheckedTagsForNote
+ uncheckedTagsForNote
}
.distinct()
.toList()
|
I've added a progress dialog as well |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Performance-wise, it definitely can be improved and should be improved, but I agree with you that fixing and testing it should be the priority
AnkiDroid/src/main/java/com/ichi2/anki/dialogs/tags/TagsDialog.kt
Outdated
Show resolved
Hide resolved
Json.decodeFromString<TagsData>(inputStream.convertToString()) | ||
} | ||
|
||
@Serializable |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is @Serializable
necessary here? I don't see a TagsData instance being serialized anywhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
kotlinx.serialization.SerializationException: Serializer for class 'TagsData' is not found.
Please ensure that class is marked as '@Serializable' and that the serialization compiler plugin is applied.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that replacing this with @Parcelize
should work (and adding : Parcelable
to the class), and Parcelables tend to be faster than Serializables, but I'm not going to block on that
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I couldn't get this working, happy for someone to take on a follow-up
@david-allison this one looks like it needs a look from you? |
@mikehardy defer to 2.18.1 I feel. Nether of these are regressions in 2.18, and this needs more time |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
esp with the progress dialog this seems like a huge improvement -
first - just not crashing
second - does have some user feedback now
seems very worthwhile to get in as a quick fix so AnKing users aren't crashing
Json.decodeFromString<TagsData>(inputStream.convertToString()) | ||
} | ||
|
||
@Serializable |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that replacing this with @Parcelize
should work (and adding : Parcelable
to the class), and Parcelables tend to be faster than Serializables, but I'm not going to block on that
AnkiDroid/src/main/java/com/ichi2/anki/dialogs/tags/TagsDialog.kt
Outdated
Show resolved
Hide resolved
Since the dialog accepts all tags, this can crash just by having too many tags fix by using `TagsFile` serialized to disk Note: using Parcelable due to API 25 issue: 15878 Fixes 16226 - too many cards Fixes 16351 - too many tags
This fixes an OutOfMemoryException on 31479 cards (AnKing) It is still exceptionally slow, to the point of being unusable Issue 16226
The operation is really slow * show (some) feedback to user * stop log spam, speeding it up * remove ANR * adds a `withContext` Issue 16226
Better optimizations are possible but I want test coverage first
Purpose / Description
TransactionTooLargeException
and anOutOfMemoryError
This is a tradeoff of stability vs performance. We should do much better here in a follow-up
Fixes
Approach
asSequence
to fix an OOMselect distinct nid
BEFORE loading the notesHow Has This Been Tested?
My S21, AnKing deck (31479 cards)
No longer crashes on AnKing
⚠️ It is still FAR too slow, needing to individually load 31k cards. This requires a follow-up issue
Checklist