Push before cleanup

This commit is contained in:
Al Lansley 2024-04-04 10:15:15 +11:00
parent 73f11c5a4f
commit d65705c845
3 changed files with 43 additions and 18 deletions

View File

@ -13,6 +13,7 @@ import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.mapLatest
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.plus
import org.session.libsignal.utilities.Log
import org.session.libsignal.utilities.SettableFuture
import org.thoughtcrime.securesms.search.SearchRepository
import org.thoughtcrime.securesms.search.model.SearchResult
@ -31,6 +32,9 @@ class GlobalSearchViewModel @Inject constructor(private val searchRepository: Se
private val _queryText: MutableStateFlow<CharSequence> = MutableStateFlow("")
private var settableFuture = SettableFuture<SearchResult>()
fun postQuery(charSequence: CharSequence?) {
charSequence ?: return
_queryText.value = charSequence
@ -41,6 +45,7 @@ class GlobalSearchViewModel @Inject constructor(private val searchRepository: Se
_queryText
.buffer(onBufferOverflow = BufferOverflow.DROP_OLDEST)
.mapLatest { query ->
// Minimum search term is 2 characters - for a single char we do nothing
if (query.trim().length < 2) {
SearchResult.EMPTY
} else {
@ -48,7 +53,13 @@ class GlobalSearchViewModel @Inject constructor(private val searchRepository: Se
// this coroutine will be cancelled and expensive query will not be run if typing quickly
// first query of 2 characters will be instant however
delay(300)
val settableFuture = SettableFuture<SearchResult>()
// If we already have a search running then stop it
if (!settableFuture.isDone) {
Log.w("[ACL]", "Cancelling settable future..")
settableFuture.cancel(true); }
settableFuture = SettableFuture<SearchResult>()
searchRepository.query(query.toString(), settableFuture::set)
try {
// search repository doesn't play nicely with suspend functions (yet)
@ -64,6 +75,4 @@ class GlobalSearchViewModel @Inject constructor(private val searchRepository: Se
}
.launchIn(executor)
}
}

View File

@ -86,7 +86,15 @@ public class SearchRepository {
}
public void query(@NonNull String query, @NonNull Callback<SearchResult> callback) {
if (TextUtils.isEmpty(query)) {
Log.w("[ACL]", "Hit SearchRepository.query - query string is: \"" + query + "\"");
String cleanQuery = sanitizeQuery(query).trim();
Log.w("[ACL]", "When sanitized and trimmed this is: \"" + cleanQuery + "\"");
// If the sanitized search is empty or is less than 2 chars then abort
if (cleanQuery.isEmpty() || cleanQuery.length() < 2) {
Log.w("[ACL]", "Trimmed query is empty or less than 2 chars so returning empty SearchResult");
callback.onResult(SearchResult.EMPTY);
return;
}
@ -94,25 +102,36 @@ public class SearchRepository {
executor.execute(() -> {
Stopwatch timer = new Stopwatch("FtsQuery");
String cleanQuery = sanitizeQuery(query);
// ACL
//String cleanQuery = sanitizeQuery(query).trim();
// If the search is for a single character and it was stripped by `sanitizeQuery` then abort
// the search for an empty string to avoid SQLite error.
if (cleanQuery.length() == 0)
/*
if (cleanQuery.isEmpty())
{
Log.w("[ACL]", "Aborting empty search query.");
Log.d(TAG, "Aborting empty search query.");
timer.stop(TAG);
return;
}
else {
Log.w("[ACL]", "Clean query is non-empty and is: \"" + cleanQuery + "\"");
}
*/
timer.split("clean");
Log.w("[ACL]", "About to query contacts.");
Pair<CursorList<Contact>, List<String>> contacts = queryContacts(cleanQuery);
timer.split("contacts");
Log.w("[ACL]", "About to query conversations.");
CursorList<GroupRecord> conversations = queryConversations(cleanQuery, contacts.getSecond());
timer.split("conversations");
Log.w("[ACL]", "About to query messages.");
CursorList<MessageResult> messages = queryMessages(cleanQuery);
timer.split("messages");
@ -123,23 +142,20 @@ public class SearchRepository {
}
public void query(@NonNull String query, long threadId, @NonNull Callback<CursorList<MessageResult>> callback) {
if (TextUtils.isEmpty(query)) {
// If the sanitized search query is empty or less than 2 chars then abort the search
String cleanQuery = sanitizeQuery(query).trim();
if (cleanQuery.isEmpty() || cleanQuery.length() < 2) {
callback.onResult(CursorList.emptyList());
return;
}
executor.execute(() -> {
// If the sanitized search query is empty then abort the search to prevent SQLite errors.
String cleanQuery = sanitizeQuery(query).trim();
if (cleanQuery.isEmpty()) { return; }
CursorList<MessageResult> messages = queryMessages(cleanQuery, threadId);
callback.onResult(messages);
});
}
private Pair<CursorList<Contact>, List<String>> queryContacts(String query) {
Cursor contacts = contactDatabase.queryContactsByName(query);
List<Address> contactList = new ArrayList<>();
List<String> contactStrings = new ArrayList<>();
@ -189,9 +205,7 @@ public class SearchRepository {
membersGroupList.close();
}
Cursor conversations = threadDatabase.getFilteredConversationList(new ArrayList<>(addresses));
return conversations != null ? new CursorList<>(conversations, new GroupModelBuilder(threadDatabase, groupDatabase))
: CursorList.emptyList();
}

View File

@ -37,13 +37,15 @@ public class Stopwatch {
for (int i = 1; i < splits.size(); i++) {
out.append(splits.get(i).label).append(": ");
out.append(splits.get(i).time - splits.get(i - 1).time);
out.append(" ");
out.append("ms ");
}
out.append("total: ").append(splits.get(splits.size() - 1).time - startTime);
out.append("total: ").append(splits.get(splits.size() - 1).time - startTime).append("ms.");
}
Log.d(tag, out.toString());
Log.w("[ACL]", out.toString());
}
private static class Split {