From 66d00d710e618a7652b8aa293136ac2a7d4d9b37 Mon Sep 17 00:00:00 2001 From: M66B Date: Sat, 9 Dec 2023 22:27:09 +0100 Subject: [PATCH] Reduced memory usage of cleanup worker --- .../java/eu/faircode/email/DaoAttachment.java | 4 +- .../java/eu/faircode/email/DaoMessage.java | 2 +- .../java/eu/faircode/email/WorkerCleanup.java | 149 +++++++++--------- 3 files changed, 77 insertions(+), 78 deletions(-) diff --git a/app/src/main/java/eu/faircode/email/DaoAttachment.java b/app/src/main/java/eu/faircode/email/DaoAttachment.java index be5d4c9a16..11b85e074d 100644 --- a/app/src/main/java/eu/faircode/email/DaoAttachment.java +++ b/app/src/main/java/eu/faircode/email/DaoAttachment.java @@ -19,6 +19,8 @@ package eu.faircode.email; Copyright 2018-2023 by Marcel Bokhorst (M66B) */ +import android.database.Cursor; + import androidx.lifecycle.LiveData; import androidx.room.Dao; import androidx.room.Insert; @@ -64,7 +66,7 @@ public interface DaoAttachment { @Query("SELECT id FROM attachment" + " WHERE available") - List getAttachmentAvailable(); + Cursor getAttachmentAvailable(); @Query("UPDATE attachment" + " SET message = :message" + diff --git a/app/src/main/java/eu/faircode/email/DaoMessage.java b/app/src/main/java/eu/faircode/email/DaoMessage.java index 4dc4cbada3..fd59c78668 100644 --- a/app/src/main/java/eu/faircode/email/DaoMessage.java +++ b/app/src/main/java/eu/faircode/email/DaoMessage.java @@ -384,7 +384,7 @@ public interface DaoMessage { " FROM message" + " WHERE content" + " ORDER BY message.received DESC") - List getMessageWithContent(); + Cursor getMessageWithContent(); @Query("SELECT message.id" + " FROM message" + diff --git a/app/src/main/java/eu/faircode/email/WorkerCleanup.java b/app/src/main/java/eu/faircode/email/WorkerCleanup.java index bc2db8fb63..0bbf57f445 100644 --- a/app/src/main/java/eu/faircode/email/WorkerCleanup.java +++ b/app/src/main/java/eu/faircode/email/WorkerCleanup.java @@ -109,8 +109,8 @@ public class WorkerCleanup extends Worker { if (manual) { // Check message files Log.i("Checking message files"); - List mids = db.message().getMessageWithContent(); - for (Long mid : mids) { + try (Cursor cursor = db.message().getMessageWithContent()) { + long mid = cursor.getLong(0); EntityMessage message = db.message().getMessage(mid); if (message != null) { File file = message.getFile(context); @@ -123,8 +123,8 @@ public class WorkerCleanup extends Worker { // Check attachments files Log.i("Checking attachments files"); - List aids = db.attachment().getAttachmentAvailable(); - for (Long aid : aids) { + try (Cursor cursor = db.attachment().getAttachmentAvailable()) { + long aid = cursor.getLong(0); EntityAttachment attachment = db.attachment().getAttachment(aid); if (attachment != null) { File file = attachment.getFile(context); @@ -206,46 +206,14 @@ public class WorkerCleanup extends Worker { long now = new Date().getTime(); - List files = new ArrayList<>(); - File[] messages = Helper.listFiles(new File(context.getFilesDir(), "messages")).toArray(new File[0]); - File[] revision = new File(context.getFilesDir(), "revision").listFiles(); - File[] references = new File(context.getFilesDir(), "references").listFiles(); - File[] encryption = new File(context.getFilesDir(), "encryption").listFiles(); - File[] photos = new File(context.getFilesDir(), "photo").listFiles(); - File[] calendars = new File(context.getFilesDir(), "calendar").listFiles(); - - if (messages != null) - files.addAll(Arrays.asList(messages)); - if (revision != null) - files.addAll(Arrays.asList(revision)); - if (references != null) - files.addAll(Arrays.asList(references)); - if (encryption != null) - files.addAll(Arrays.asList(encryption)); - if (photos != null) - files.addAll(Arrays.asList(photos)); - if (calendars != null) - files.addAll(Arrays.asList(calendars)); - // Cleanup message files Log.i("Cleanup message files"); - for (File file : files) - if (manual || file.lastModified() + KEEP_FILES_DURATION < now) - try { - String name = file.getName().split("\\.")[0]; - int us = name.indexOf('_'); - if (us > 0) - name = name.substring(0, us); - long id = Long.parseLong(name); - EntityMessage message = db.message().getMessage(id); - if (message == null || !message.content) { - Log.i("Deleting " + file); - Helper.secureDelete(file); - } - } catch (NumberFormatException ex) { - Log.e(file.getAbsolutePath(), ex); - Helper.secureDelete(file); - } + cleanupMessageFiles(db, manual, Helper.listFiles(new File(context.getFilesDir(), "messages")).toArray(new File[0])); + cleanupMessageFiles(db, manual, new File(context.getFilesDir(), "revision").listFiles()); + cleanupMessageFiles(db, manual, new File(context.getFilesDir(), "references").listFiles()); + cleanupMessageFiles(db, manual, new File(context.getFilesDir(), "encryption").listFiles()); + cleanupMessageFiles(db, manual, new File(context.getFilesDir(), "photo").listFiles()); + cleanupMessageFiles(db, manual, new File(context.getFilesDir(), "calendar").listFiles()); // Cleanup raw message files if (!download_eml) { @@ -276,49 +244,55 @@ public class WorkerCleanup extends Worker { // Cleanup attachment files Log.i("Cleanup attachment files"); - File[] attachments = new File(EntityAttachment.getRoot(context), "attachments").listFiles(); - if (attachments != null) - for (File file : attachments) - if (manual || file.lastModified() + KEEP_FILES_DURATION < now) - try { - long id = Long.parseLong(file.getName().split("\\.")[0]); - EntityAttachment attachment = db.attachment().getAttachment(id); - if (attachment == null || !attachment.available) { - Log.i("Deleting " + file); + { + File[] attachments = new File(EntityAttachment.getRoot(context), "attachments").listFiles(); + if (attachments != null) + for (File file : attachments) + if (manual || file.lastModified() + KEEP_FILES_DURATION < now) + try { + long id = Long.parseLong(file.getName().split("\\.")[0]); + EntityAttachment attachment = db.attachment().getAttachment(id); + if (attachment == null || !attachment.available) { + Log.i("Deleting " + file); + Helper.secureDelete(file); + } + } catch (NumberFormatException ex) { + Log.e(file.getAbsolutePath(), ex); Helper.secureDelete(file); } - } catch (NumberFormatException ex) { - Log.e(file.getAbsolutePath(), ex); - Helper.secureDelete(file); - } + } // Cleanup cached images Log.i("Cleanup cached image files"); - File[] images = new File(context.getFilesDir(), "images").listFiles(); - if (images != null) - for (File file : images) - if (manual || file.lastModified() + KEEP_FILES_DURATION < now) - try { - long id = Long.parseLong(file.getName().split("[_\\.]")[0]); - EntityMessage message = db.message().getMessage(id); - if (manual || message == null || - file.lastModified() + KEEP_IMAGES_DURATION < now) { - Log.i("Deleting " + file); + { + File[] images = new File(context.getFilesDir(), "images").listFiles(); + if (images != null) + for (File file : images) + if (manual || file.lastModified() + KEEP_FILES_DURATION < now) + try { + long id = Long.parseLong(file.getName().split("[_\\.]")[0]); + EntityMessage message = db.message().getMessage(id); + if (manual || message == null || + file.lastModified() + KEEP_IMAGES_DURATION < now) { + Log.i("Deleting " + file); + Helper.secureDelete(file); + } + } catch (NumberFormatException ex) { + Log.e(file.getAbsolutePath(), ex); Helper.secureDelete(file); } - } catch (NumberFormatException ex) { - Log.e(file.getAbsolutePath(), ex); - Helper.secureDelete(file); - } + } // Cleanup shared files - File[] shared = new File(context.getFilesDir(), "shared").listFiles(); - if (shared != null) - for (File file : shared) - if (manual || file.lastModified() + KEEP_FILES_DURATION < now) { - Log.i("Deleting " + file); - Helper.secureDelete(file); - } + { + File[] shared = new File(context.getFilesDir(), "shared").listFiles(); + if (shared != null) + for (File file : shared) + if (manual || file.lastModified() + KEEP_FILES_DURATION < now) { + Log.i("Deleting " + file); + Helper.secureDelete(file); + } + } // Cleanup contact info if (manual) @@ -400,6 +374,29 @@ public class WorkerCleanup extends Worker { } } + static void cleanupMessageFiles(DB db, boolean manual, File[] files) { + if (files == null) + return; + long now = new Date().getTime(); + for (File file : files) + if (manual || file.lastModified() + KEEP_FILES_DURATION < now) + try { + String name = file.getName().split("\\.")[0]; + int us = name.indexOf('_'); + if (us > 0) + name = name.substring(0, us); + long id = Long.parseLong(name); + EntityMessage message = db.message().getMessage(id); + if (message == null || !message.content) { + Log.i("Deleting " + file); + Helper.secureDelete(file); + } + } catch (NumberFormatException ex) { + Log.e(file.getAbsolutePath(), ex); + Helper.secureDelete(file); + } + } + static void init(Context context) { try { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);