1
0
Fork 0

word pairs are now deleted when a language is deleted; DataStore code cleanup

This commit is contained in:
sspanak 2024-10-16 18:41:22 +03:00 committed by Dimo Karaivanov
parent d47528f550
commit a46be312c0
6 changed files with 97 additions and 62 deletions

View file

@ -26,4 +26,22 @@ public class BaseSyncStore {
return true;
}
public void startTransaction() {
if (sqlite != null) {
sqlite.beginTransaction();
}
}
public void failTransaction() {
if (sqlite != null) {
sqlite.failTransaction();
}
}
public void finishTransaction() {
if (sqlite != null) {
sqlite.finishTransaction();
}
}
}

View file

@ -13,6 +13,7 @@ import io.github.sspanak.tt9.db.words.DictionaryLoader;
import io.github.sspanak.tt9.db.words.WordStore;
import io.github.sspanak.tt9.languages.Language;
import io.github.sspanak.tt9.util.ConsumerCompat;
import io.github.sspanak.tt9.util.Logger;
public class DataStore {
private static final Handler asyncHandler = new Handler();
@ -26,67 +27,92 @@ public class DataStore {
}
private static void runInThread(@NonNull Runnable action) {
new Thread(action).start();
}
private static void runInTransaction(@NonNull Runnable action, @NonNull Runnable onFinish, @NonNull String errorMessagePrefix) {
runInThread(() -> {
try {
words.startTransaction();
action.run();
words.finishTransaction();
} catch (Exception e) {
words.failTransaction();
Logger.e(DataStore.class.getSimpleName(), errorMessagePrefix + " " + e.getMessage());
}
onFinish.run();
});
}
public static void normalizeNext() {
new Thread(() -> words.normalizeNext()).start();
runInThread(() -> words.normalizeNext());
}
public static void getLastLanguageUpdateTime(ConsumerCompat<String> notification, Language language) {
new Thread(() -> notification.accept(words.getLanguageFileHash(language))).start();
runInThread(() -> notification.accept(words.getLanguageFileHash(language)));
}
public static void deleteCustomWord(Runnable notification, Language language, String word) {
new Thread(() -> {
runInThread(() -> {
words.removeCustomWord(language, word);
notification.run();
}).start();
});
}
public static void deleteWords(Runnable notification, @NonNull ArrayList<Integer> languageIds) {
new Thread(() -> {
words.remove(languageIds);
notification.run();
}).start();
public static void deleteLanguages(Runnable notification, @NonNull ArrayList<Language> languages) {
runInTransaction(
() -> { words.remove(languages); pairs.remove(languages); },
notification,
"Failed deleting languages."
);
}
public static void put(ConsumerCompat<AddWordResult> statusHandler, Language language, String word) {
new Thread(() -> statusHandler.accept(words.put(language, word))).start();
runInThread(() -> statusHandler.accept(words.put(language, word)));
}
public static void makeTopWord(@NonNull Language language, @NonNull String word, @NonNull String sequence) {
new Thread(() -> words.makeTopWord(language, word, sequence)).start();
runInThread(() -> words.makeTopWord(language, word, sequence));
}
public static void getWords(ConsumerCompat<ArrayList<String>> dataHandler, Language language, String sequence, String filter, int minWords, int maxWords) {
new Thread(() -> asyncHandler.post(() -> dataHandler.accept(
words.getSimilar(language, sequence, filter, minWords, maxWords)))
).start();
runInThread(() -> {
ArrayList<String> data = words.getSimilar(language, sequence, filter, minWords, maxWords);
asyncHandler.post(() -> dataHandler.accept(data));
});
}
public static void getCustomWords(ConsumerCompat<ArrayList<String>> dataHandler, String wordFilter, int maxWords) {
new Thread(() -> asyncHandler.post(() -> dataHandler.accept(
words.getSimilarCustom(wordFilter, maxWords)))
).start();
runInThread(() -> {
ArrayList<String> data = words.getSimilarCustom(wordFilter, maxWords);
asyncHandler.post(() -> dataHandler.accept(data));
});
}
public static void countCustomWords(ConsumerCompat<Long> dataHandler) {
new Thread(() -> asyncHandler.post(() -> dataHandler.accept(
words.countCustom()))
).start();
runInThread(() -> {
long data = words.countCustom();
asyncHandler.post(() -> dataHandler.accept(data));
});
}
public static void exists(ConsumerCompat<ArrayList<Integer>> dataHandler, ArrayList<Language> languages) {
new Thread(() -> asyncHandler.post(() -> dataHandler.accept(
words.exists(languages))
)).start();
runInThread(() -> {
ArrayList<Integer> data = words.exists(languages);
asyncHandler.post(() -> dataHandler.accept(data));
});
}
@ -101,12 +127,12 @@ public class DataStore {
public static void saveWordPairs() {
new Thread(() -> pairs.save()).start();
runInThread(() -> pairs.save());
}
public static void loadWordPairs(DictionaryLoader dictionaryLoader, ArrayList<Language> languages) {
new Thread(() -> pairs.load(dictionaryLoader, languages)).start();
runInThread(() -> pairs.load(dictionaryLoader, languages));
}
@ -114,11 +140,9 @@ public class DataStore {
pairs.clearCache();
}
public static void deleteWordPairs(@NonNull ArrayList<Language> languages, @NonNull Runnable onDeleted) {
new Thread(() -> {
pairs.delete(languages);
onDeleted.run();
}).start();
runInTransaction(() -> pairs.remove(languages), onDeleted, "Failed deleting word pairs.");
}

View file

@ -21,6 +21,8 @@ import io.github.sspanak.tt9.util.Logger;
import io.github.sspanak.tt9.util.Timer;
public class WordPairStore extends BaseSyncStore {
private static final String LOG_TAG = WordPairStore.class.getSimpleName();
// data
private final ConcurrentHashMap<Integer, HashMap<WordPair, WordPair>> pairs = new ConcurrentHashMap<>();
@ -111,7 +113,7 @@ public class WordPairStore extends BaseSyncStore {
long currentTime = Timer.stop(SAVE_TIMER_NAME);
slowestSaveTime = Math.max(slowestSaveTime, currentTime);
Logger.d(getClass().getSimpleName(), "Saved all word pairs in: " + currentTime + " ms");
Logger.d(LOG_TAG, "Saved all word pairs in: " + currentTime + " ms");
}
@ -121,12 +123,12 @@ public class WordPairStore extends BaseSyncStore {
}
if (dictionaryLoader.isRunning()) {
Logger.e(getClass().getSimpleName(), "Cannot load word pairs while the DictionaryLoader is working.");
Logger.e(LOG_TAG, "Cannot load word pairs while the DictionaryLoader is working.");
return;
}
if (languages == null) {
Logger.e(getClass().getSimpleName(), "Cannot load word pairs for NULL language list.");
Logger.e(LOG_TAG, "Cannot load word pairs for NULL language list.");
return;
}
@ -149,25 +151,27 @@ public class WordPairStore extends BaseSyncStore {
wordPairs.put(pair, pair);
}
Logger.d(getClass().getSimpleName(), "Loaded " + wordPairs.size() + " word pairs for language: " + language.getId());
Logger.d(LOG_TAG, "Loaded " + wordPairs.size() + " word pairs for language: " + language.getId());
}
long currentTime = Timer.stop(LOAD_TIMER_NAME);
slowestLoadTime = Math.max(slowestLoadTime, currentTime);
Logger.d(getClass().getSimpleName(), "Loaded " + totalPairs + " word pairs in " + currentTime + " ms");
Logger.d(LOG_TAG, "Loaded " + totalPairs + " word pairs in " + currentTime + " ms");
}
public void delete(@NonNull ArrayList<Language> languages) {
public void remove(@NonNull ArrayList<Language> languages) {
if (!checkOrNotify()) {
return;
}
sqlite.beginTransaction();
Timer.start(LOG_TAG);
for (Language language : languages) {
DeleteOps.deleteWordPairs(sqlite.getDb(), language.getId());
}
sqlite.finishTransaction();
Logger.d(LOG_TAG, "Deleted " + languages.size() + " word pair groups. Time: " + Timer.stop(LOG_TAG) + " ms");
slowestLoadTime = 0;
slowestSaveTime = 0;

View file

@ -109,26 +109,20 @@ public class WordStore extends BaseSyncStore {
}
public void remove(ArrayList<Integer> languageIds) {
public void remove(ArrayList<Language> languages) {
if (!checkOrNotify()) {
return;
}
Timer.start(LOG_TAG);
try {
sqlite.beginTransaction();
for (int langId : languageIds) {
if (readOps.exists(sqlite.getDb(), langId)) {
DeleteOps.delete(sqlite.getDb(), langId);
}
}
sqlite.finishTransaction();
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());
for (Language lang : languages) {
if (readOps.exists(sqlite.getDb(), lang.getId())) {
DeleteOps.delete(sqlite.getDb(), lang.getId());
}
}
Logger.d(LOG_TAG, "Deleted " + languages.size() + " languages. Time: " + Timer.stop(LOG_TAG) + " ms");
}

View file

@ -2,11 +2,8 @@ package io.github.sspanak.tt9.preferences.screens.languages;
import androidx.preference.Preference;
import java.util.ArrayList;
import io.github.sspanak.tt9.R;
import io.github.sspanak.tt9.db.DataStore;
import io.github.sspanak.tt9.languages.Language;
import io.github.sspanak.tt9.languages.LanguageCollection;
import io.github.sspanak.tt9.preferences.PreferencesActivity;
import io.github.sspanak.tt9.preferences.items.ItemClickable;
@ -32,11 +29,7 @@ class ItemTruncateAll extends ItemClickable {
@Override
protected boolean onClick(Preference p) {
onStartDeleting();
ArrayList<Integer> languageIds = new ArrayList<>();
for (Language lang : LanguageCollection.getAll(activity, false)) {
languageIds.add(lang.getId());
}
DataStore.deleteWords(this::onFinishDeleting, languageIds);
DataStore.deleteLanguages(this::onFinishDeleting, LanguageCollection.getAll(activity, false));
return true;
}

View file

@ -3,6 +3,8 @@ package io.github.sspanak.tt9.preferences.screens.languages;
import androidx.preference.Preference;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
import io.github.sspanak.tt9.db.DataStore;
import io.github.sspanak.tt9.languages.Language;
@ -21,16 +23,16 @@ class ItemTruncateUnselected extends ItemTruncateAll {
@Override
protected boolean onClick(Preference p) {
ArrayList<Integer> unselectedLanguageIds = new ArrayList<>();
ArrayList<Integer> selectedLanguageIds = activity.getSettings().getEnabledLanguageIds();
ArrayList<Language> unselectedLanguages = new ArrayList<>();
Set<Integer> selectedLanguageIds = new HashSet<>(activity.getSettings().getEnabledLanguageIds());
for (Language lang : LanguageCollection.getAll(activity, false)) {
if (!selectedLanguageIds.contains(lang.getId())) {
unselectedLanguageIds.add(lang.getId());
unselectedLanguages.add(lang);
}
}
onStartDeleting();
DataStore.deleteWords(this::onFinishDeleting, unselectedLanguageIds);
DataStore.deleteLanguages(this::onFinishDeleting, unselectedLanguages);
return true;
}