diff --git a/Clover/app/src/main/java/org/floens/chan/core/manager/WatchManager.java b/Clover/app/src/main/java/org/floens/chan/core/manager/WatchManager.java index 61a9798d..290ae145 100644 --- a/Clover/app/src/main/java/org/floens/chan/core/manager/WatchManager.java +++ b/Clover/app/src/main/java/org/floens/chan/core/manager/WatchManager.java @@ -151,17 +151,10 @@ public class WatchManager implements ChanApplication.ForegroundChangedListener { } /** - * Updates all the pins to the database. This will run in a new thread - * because it can be an expensive operation. (this will be an huge headache - * later on when we get concurrent problems) + * Updates all the pins to the database. */ public void updateDatabase() { - new Thread(new Runnable() { - @Override - public void run() { - ChanApplication.getDatabaseManager().updatePins(pins); - } - }).start(); + ChanApplication.getDatabaseManager().updatePins(pins); } public void addPinListener(PinListener l) { diff --git a/Clover/app/src/main/java/org/floens/chan/database/DatabaseManager.java b/Clover/app/src/main/java/org/floens/chan/database/DatabaseManager.java index 2d4dc9d2..a9fa808e 100644 --- a/Clover/app/src/main/java/org/floens/chan/database/DatabaseManager.java +++ b/Clover/app/src/main/java/org/floens/chan/database/DatabaseManager.java @@ -26,14 +26,19 @@ import org.floens.chan.utils.Logger; import org.floens.chan.utils.Time; import java.sql.SQLException; +import java.util.HashSet; import java.util.List; import java.util.concurrent.Callable; public class DatabaseManager { private static final String TAG = "DatabaseManager"; + private static final long SAVED_REPLY_TRIM_TRIGGER = 250; + private static final long SAVED_REPLY_TRIM_COUNT = 50; + private final DatabaseHelper helper; private List savedReplies; + private HashSet savedRepliesIds = new HashSet<>(); public DatabaseManager(Context context) { helper = new DatabaseHelper(context); @@ -56,10 +61,11 @@ public class DatabaseManager { loadSavedReplies(); } - // TODO: optimize this - for (SavedReply r : savedReplies) { - if (r.board.equals(board) && r.no == no) { - return r; + if (savedRepliesIds.contains(no)) { + for (SavedReply r : savedReplies) { + if (r.no == no && r.board.equals(board)) { + return r; + } } } @@ -71,14 +77,33 @@ public class DatabaseManager { } private void loadSavedReplies() { - // TODO trim the table if it gets too large try { savedReplies = helper.savedDao.queryForAll(); + savedRepliesIds.clear(); + for (SavedReply reply : savedReplies) { + savedRepliesIds.add(reply.no); + } + + long count = helper.savedDao.countOf(); + if (count >= SAVED_REPLY_TRIM_TRIGGER) { + trimSavedRepliesTable(SAVED_REPLY_TRIM_COUNT + (count - SAVED_REPLY_TRIM_TRIGGER)); + } } catch (SQLException e) { Logger.e(TAG, "Error loading saved replies", e); } } + public void trimSavedRepliesTable(long limit) { + try { + Logger.i(TAG, "Trimming the length of the savedreply table for " + limit + " rows, was " + helper.savedDao.countOf()); + helper.savedDao.executeRaw("DELETE FROM savedreply WHERE id IN " + + "(SELECT id FROM savedreply ORDER BY id ASC LIMIT ?)", Long.toString(limit)); + Logger.i(TAG, "The savedreply table now has " + helper.savedDao.countOf() + " rows"); + } catch (SQLException e) { + Logger.e(TAG, "Error trimming saved replies table", e); + } + } + public void addPin(Pin pin) { try { helper.loadableDao.create(pin.loadable); @@ -106,16 +131,23 @@ public class DatabaseManager { } } - public void updatePins(List pins) { + public void updatePins(final List pins) { try { - for (Pin pin : pins) { - helper.pinDao.update(pin); - } + helper.pinDao.callBatchTasks(new Callable() { + @Override + public Void call() throws SQLException { + for (Pin pin : pins) { + helper.pinDao.update(pin); + } - for (Pin pin : pins) { - helper.loadableDao.update(pin.loadable); - } - } catch (SQLException e) { + for (Pin pin : pins) { + helper.loadableDao.update(pin.loadable); + } + + return null; + } + }); + } catch (Exception e) { Logger.e(TAG, "Error updating pins in db", e); } } diff --git a/Clover/app/src/main/java/org/floens/chan/ui/activity/DeveloperActivity.java b/Clover/app/src/main/java/org/floens/chan/ui/activity/DeveloperActivity.java index c0d2f8e1..22c802dd 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/activity/DeveloperActivity.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/activity/DeveloperActivity.java @@ -25,8 +25,11 @@ import android.widget.LinearLayout; import android.widget.TextView; import org.floens.chan.ChanApplication; +import org.floens.chan.core.model.SavedReply; import org.floens.chan.utils.ThemeHelper; +import java.util.Random; + public class DeveloperActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { @@ -71,6 +74,33 @@ public class DeveloperActivity extends Activity { resetDbButton.setText("Delete database"); wrapper.addView(resetDbButton); + Button savedReplyDummyAdd = new Button(this); + savedReplyDummyAdd.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(final View v) { + Random r = new Random(); + int j = 0; + for (int i = 0; i < 100; i++) { + j += r.nextInt(10000); + ChanApplication.getDatabaseManager().saveReply(new SavedReply("g", j, "pass")); + } + recreate(); + } + }); + savedReplyDummyAdd.setText("Add test rows to savedReply"); + wrapper.addView(savedReplyDummyAdd); + + Button trimSavedReply = new Button(this); + trimSavedReply.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(final View v) { + ChanApplication.getDatabaseManager().trimSavedRepliesTable(10); + recreate(); + } + }); + trimSavedReply.setText("Trim savedreply table"); + wrapper.addView(trimSavedReply); + setContentView(wrapper); } }