From 42cf53787a0b46e5f01281864d94a25ef23ba761 Mon Sep 17 00:00:00 2001 From: sspanak Date: Mon, 18 Mar 2024 17:39:36 +0200 Subject: [PATCH] added a Timer class --- .../java/io/github/sspanak/tt9/Timer.java | 39 ++++++++++++++++++ .../sspanak/tt9/db/DictionaryLoader.java | 41 ++++++++----------- .../io/github/sspanak/tt9/db/WordStore.java | 23 ++++++----- .../tt9/db/exporter/DictionaryExporter.java | 5 ++- .../github/sspanak/tt9/ime/KeyPadHandler.java | 12 +++--- 5 files changed, 76 insertions(+), 44 deletions(-) create mode 100644 app/src/main/java/io/github/sspanak/tt9/Timer.java diff --git a/app/src/main/java/io/github/sspanak/tt9/Timer.java b/app/src/main/java/io/github/sspanak/tt9/Timer.java new file mode 100644 index 00000000..6c5f192a --- /dev/null +++ b/app/src/main/java/io/github/sspanak/tt9/Timer.java @@ -0,0 +1,39 @@ +package io.github.sspanak.tt9; + +import java.util.HashMap; + +public class Timer { + private static final HashMap timers = new HashMap<>(); + + public static void start() { + start("default"); + } + + public static long stop() { + return stop("default"); + } + + public static long restart() { + long time = stop(); + start(); + return time; + } + + public static long get(String timerName) { + Long startTime = timers.get(timerName); + if (startTime == null) { + return -1; + } + return System.currentTimeMillis() - startTime; + } + + public static void start(String timerName) { + timers.put(timerName, System.currentTimeMillis()); + } + + public static long stop(String timerName) { + long time = get(timerName); + timers.remove(timerName); + return time; + } +} diff --git a/app/src/main/java/io/github/sspanak/tt9/db/DictionaryLoader.java b/app/src/main/java/io/github/sspanak/tt9/db/DictionaryLoader.java index 29454a05..1a09c193 100644 --- a/app/src/main/java/io/github/sspanak/tt9/db/DictionaryLoader.java +++ b/app/src/main/java/io/github/sspanak/tt9/db/DictionaryLoader.java @@ -12,6 +12,7 @@ import java.util.Locale; import io.github.sspanak.tt9.ConsumerCompat; import io.github.sspanak.tt9.Logger; +import io.github.sspanak.tt9.Timer; import io.github.sspanak.tt9.db.entities.WordBatch; import io.github.sspanak.tt9.db.entities.WordFile; import io.github.sspanak.tt9.db.exceptions.DictionaryImportAbortedException; @@ -32,6 +33,7 @@ import io.github.sspanak.tt9.ui.UI; public class DictionaryLoader { private static final String LOG_TAG = "DictionaryLoader"; private static DictionaryLoader self; + private static final String IMPORT_TIMER = "importTime"; private final AssetManager assets; private final SQLiteOpener sqlite; @@ -42,7 +44,6 @@ public class DictionaryLoader { private final HashMap lastAutoLoadAttemptTime = new HashMap<>(); private int currentFile = 0; - private long importStartTime = 0; private long lastProgressUpdate = 0; @@ -67,17 +68,12 @@ public class DictionaryLoader { } - private long getImportTime() { - return System.currentTimeMillis() - importStartTime; - } - - public boolean load(ArrayList languages) { if (isRunning()) { return false; } - if (languages == null || languages.size() == 0) { + if (languages == null || languages.isEmpty()) { Logger.d(LOG_TAG, "Nothing to do"); return true; } @@ -86,7 +82,7 @@ public class DictionaryLoader { @Override public void run() { currentFile = 0; - importStartTime = System.currentTimeMillis(); + Timer.start(IMPORT_TIMER); sendStartMessage(languages.size()); @@ -144,6 +140,7 @@ public class DictionaryLoader { public void stop() { loadThread.interrupt(); + Timer.stop(IMPORT_TIMER); } @@ -160,52 +157,48 @@ public class DictionaryLoader { } try { - long start = System.currentTimeMillis(); + Timer.start(); + float progress = 1; sqlite.beginTransaction(); Tables.dropIndexes(sqlite.getDb(), language); sendProgressMessage(language, ++progress, SettingsStore.DICTIONARY_IMPORT_PROGRESS_UPDATE_TIME); - logLoadingStep("Indexes dropped", language, start); + logLoadingStep("Indexes dropped", language, Timer.restart()); - start = System.currentTimeMillis(); DeleteOps.delete(sqlite.getDb(), language.getId()); DeleteOps.delete(sqlite.getDb(), new EmojiLanguage().getId()); sendProgressMessage(language, ++progress, SettingsStore.DICTIONARY_IMPORT_PROGRESS_UPDATE_TIME); - logLoadingStep("Storage cleared", language, start); + logLoadingStep("Storage cleared", language, Timer.restart()); - start = System.currentTimeMillis(); int lettersCount = importLetters(language); sendProgressMessage(language, ++progress, SettingsStore.DICTIONARY_IMPORT_PROGRESS_UPDATE_TIME); - logLoadingStep("Letters imported", language, start); + logLoadingStep("Letters imported", language, Timer.restart()); - start = System.currentTimeMillis(); importWordFile(language, lettersCount, progress, 88); progress = 88; sendProgressMessage(language, progress, SettingsStore.DICTIONARY_IMPORT_PROGRESS_UPDATE_TIME); - logLoadingStep("Dictionary file imported", language, start); + logLoadingStep("Dictionary file imported", language, Timer.restart()); - start = System.currentTimeMillis(); DeleteOps.purgeCustomWords(sqlite.getDb(), language.getId()); sendProgressMessage(language, ++progress, SettingsStore.DICTIONARY_IMPORT_PROGRESS_UPDATE_TIME); - logLoadingStep("Removed custom words, which are already in the dictionary", language, start); + logLoadingStep("Removed custom words, which are already in the dictionary", language, Timer.restart()); - start = System.currentTimeMillis(); InsertOps.restoreCustomWords(sqlite.getDb(), language); InsertOps.restoreCustomWords(sqlite.getDb(), new EmojiLanguage()); sendProgressMessage(language, ++progress, SettingsStore.DICTIONARY_IMPORT_PROGRESS_UPDATE_TIME); - logLoadingStep("Custom words restored", language, start); + logLoadingStep("Custom words restored", language, Timer.restart()); - start = System.currentTimeMillis(); Tables.createPositionIndex(sqlite.getDb(), language); sendProgressMessage(language, progress + (100f - progress) / 2f, 0); Tables.createWordIndex(sqlite.getDb(), language); sendProgressMessage(language, 100, 0); - logLoadingStep("Indexes restored", language, start); + logLoadingStep("Indexes restored", language, Timer.restart()); sqlite.finishTransaction(); SlowQueryStats.clear(); + Timer.stop(IMPORT_TIMER); } catch (DictionaryImportAbortedException e) { sqlite.failTransaction(); stop(); @@ -336,7 +329,7 @@ public class DictionaryLoader { Bundle progressMsg = new Bundle(); progressMsg.putInt("languageId", language.getId()); - progressMsg.putLong("time", getImportTime()); + progressMsg.putLong("time", Timer.get(IMPORT_TIMER)); progressMsg.putInt("progress", Math.round(progress)); progressMsg.putInt("currentFile", currentFile); asyncHandler.post(() -> onStatusChange.accept(progressMsg)); @@ -373,7 +366,7 @@ public class DictionaryLoader { private void logLoadingStep(String message, Language language, long time) { if (Logger.isDebugLevel()) { - Logger.d(LOG_TAG, message + " for language '" + language.getName() + "' in: " + (System.currentTimeMillis() - time) + " ms"); + Logger.d(LOG_TAG, message + " for language '" + language.getName() + "' in: " + time + " ms"); } } } diff --git a/app/src/main/java/io/github/sspanak/tt9/db/WordStore.java b/app/src/main/java/io/github/sspanak/tt9/db/WordStore.java index cc39a9ca..28659f77 100644 --- a/app/src/main/java/io/github/sspanak/tt9/db/WordStore.java +++ b/app/src/main/java/io/github/sspanak/tt9/db/WordStore.java @@ -7,6 +7,7 @@ import androidx.annotation.NonNull; import java.util.ArrayList; import io.github.sspanak.tt9.Logger; +import io.github.sspanak.tt9.Timer; import io.github.sspanak.tt9.db.entities.Word; import io.github.sspanak.tt9.db.entities.WordList; import io.github.sspanak.tt9.db.sqlite.DeleteOps; @@ -76,13 +77,13 @@ public class WordStore { final int maxWords = Math.max(maximumWords, minWords); final String filter = wordFilter == null ? "" : wordFilter; - long startTime = System.currentTimeMillis(); + Timer.start("get_positions"); String positions = readOps.getSimilarWordPositions(sqlite.getDb(), language, sequence, filter, minWords); - long positionsTime = System.currentTimeMillis() - startTime; + long positionsTime = Timer.stop("get_positions"); - startTime = System.currentTimeMillis(); + Timer.start("get_words"); ArrayList words = readOps.getWords(sqlite.getDb(), language, positions, filter, maxWords, false).toStringList(); - long wordsTime = System.currentTimeMillis() - startTime; + long wordsTime = Timer.stop("get_words"); printLoadingSummary(sequence, words, positionsTime, wordsTime); SlowQueryStats.add(SlowQueryStats.generateKey(language, sequence, wordFilter, minWords), (int) (positionsTime + wordsTime), positions); @@ -111,7 +112,7 @@ public class WordStore { return; } - long start = System.currentTimeMillis(); + Timer.start(LOG_TAG); try { sqlite.beginTransaction(); for (int langId : languageIds) { @@ -121,7 +122,7 @@ public class WordStore { } sqlite.finishTransaction(); - Logger.d(LOG_TAG, "Deleted " + languageIds.size() + " languages. Time: " + (System.currentTimeMillis() - start) + " ms"); + Logger.d(LOG_TAG, "Deleted " + languageIds.size() + " languages. Time: " + Timer.stop(LOG_TAG) + " ms"); } catch (Exception e) { sqlite.failTransaction(); Logger.e(LOG_TAG, "Failed deleting languages. " + e.getMessage()); @@ -200,7 +201,7 @@ public class WordStore { } try { - long start = System.currentTimeMillis(); + Timer.start(LOG_TAG); String topWordPositions = readOps.getWordPositions(sqlite.getDb(), language, sequence, 0, 0, ""); WordList topWords = readOps.getWords(sqlite.getDb(), language, topWordPositions, "", 9999, true); @@ -210,7 +211,7 @@ public class WordStore { Word topWord = topWords.get(0); if (topWord.word.toUpperCase(language.getLocale()).equals(word.toUpperCase(language.getLocale()))) { - Logger.d(LOG_TAG, "Word '" + word + "' is already the top word. Time: " + (System.currentTimeMillis() - start) + " ms"); + Logger.d(LOG_TAG, "Word '" + word + "' is already the top word. Time: " + Timer.stop(LOG_TAG) + " ms"); return; } @@ -232,7 +233,7 @@ public class WordStore { scheduleNormalization(language); } - Logger.d(LOG_TAG, "Changed frequency of '" + word + "' to: " + newTopFrequency + ". Time: " + (System.currentTimeMillis() - start) + " ms"); + Logger.d(LOG_TAG, "Changed frequency of '" + word + "' to: " + newTopFrequency + ". Time: " + Timer.stop(LOG_TAG) + " ms"); } catch (Exception e) { Logger.e(LOG_TAG,"Frequency change failed. Word: '" + word + "'. " + e.getMessage()); } @@ -244,7 +245,7 @@ public class WordStore { return; } - long start = System.currentTimeMillis(); + Timer.start(LOG_TAG); try { sqlite.beginTransaction(); @@ -253,7 +254,7 @@ public class WordStore { sqlite.finishTransaction(); String message = nextLangId > 0 ? "Normalized language: " + nextLangId : "No languages to normalize"; - Logger.d(LOG_TAG, message + ". Time: " + (System.currentTimeMillis() - start) + " ms"); + Logger.d(LOG_TAG, message + ". Time: " + Timer.stop(LOG_TAG) + " ms"); } catch (Exception e) { sqlite.failTransaction(); Logger.e(LOG_TAG, "Normalization failed. " + e.getMessage()); diff --git a/app/src/main/java/io/github/sspanak/tt9/db/exporter/DictionaryExporter.java b/app/src/main/java/io/github/sspanak/tt9/db/exporter/DictionaryExporter.java index dce91252..2322071f 100644 --- a/app/src/main/java/io/github/sspanak/tt9/db/exporter/DictionaryExporter.java +++ b/app/src/main/java/io/github/sspanak/tt9/db/exporter/DictionaryExporter.java @@ -9,6 +9,7 @@ import java.util.ArrayList; import io.github.sspanak.tt9.Logger; import io.github.sspanak.tt9.R; +import io.github.sspanak.tt9.Timer; import io.github.sspanak.tt9.db.sqlite.ReadOps; import io.github.sspanak.tt9.db.sqlite.SQLiteOpener; import io.github.sspanak.tt9.languages.Language; @@ -77,9 +78,9 @@ public class DictionaryExporter extends AbstractExporter { return; } - long start = System.currentTimeMillis(); + Timer.start(LOG_TAG); write(activity); - Logger.d(LOG_TAG, "All words for language '" + currentLanguage.getName() + "' exported. Time: " + (System.currentTimeMillis() - start) + "ms"); + Logger.d(LOG_TAG, "All words for language '" + currentLanguage.getName() + "' exported. Time: " + Timer.stop(LOG_TAG) + "ms"); } private void logExportError(Exception e) { diff --git a/app/src/main/java/io/github/sspanak/tt9/ime/KeyPadHandler.java b/app/src/main/java/io/github/sspanak/tt9/ime/KeyPadHandler.java index a201a8e9..dc7c6167 100644 --- a/app/src/main/java/io/github/sspanak/tt9/ime/KeyPadHandler.java +++ b/app/src/main/java/io/github/sspanak/tt9/ime/KeyPadHandler.java @@ -6,9 +6,8 @@ import android.view.View; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputConnection; -import java.util.HashMap; - import io.github.sspanak.tt9.Logger; +import io.github.sspanak.tt9.Timer; import io.github.sspanak.tt9.ime.helpers.Key; import io.github.sspanak.tt9.preferences.SettingsStore; import io.github.sspanak.tt9.preferences.screens.debug.ItemInputHandlingMode; @@ -18,7 +17,7 @@ abstract class KeyPadHandler extends InputMethodService { protected SettingsStore settings; // debounce handling - private final HashMap lastKeyTime = new HashMap<>(); + private final static String DEBOUNCE_TIMER = "debounce_"; // temporal key handling private boolean isBackspaceHandled = false; @@ -310,15 +309,14 @@ abstract class KeyPadHandler extends InputMethodService { return false; } - long now = System.currentTimeMillis(); - Long lastTime = lastKeyTime.get(keyCode); + String keyTimer = DEBOUNCE_TIMER + keyCode; - if (lastTime != null && now - lastTime < settings.getKeyPadDebounceTime()) { + if (Timer.get(keyTimer) > 0 && Timer.get(keyTimer) < settings.getKeyPadDebounceTime()) { return true; } if (event.getAction() == KeyEvent.ACTION_UP) { - lastKeyTime.put(keyCode, now); + Timer.start(keyTimer); } return false;