diff options
author | Christian Schneppe <christian@pix-art.de> | 2018-04-30 23:38:29 +0200 |
---|---|---|
committer | Christian Schneppe <christian@pix-art.de> | 2018-04-30 23:38:29 +0200 |
commit | ce2ba629bd91897f74e2d1dee38f90671b0f28f8 (patch) | |
tree | 678491f31abef9c735e9bada9ba20204c5cd1c2f /src/main/java/de/pixart/messenger/services/MessageSearchTask.java | |
parent | 032fbad95ce7384de922d7c3c9ac53303ab11732 (diff) |
very much unoptimized search functionality
Diffstat (limited to '')
-rw-r--r-- | src/main/java/de/pixart/messenger/services/MessageSearchTask.java | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/src/main/java/de/pixart/messenger/services/MessageSearchTask.java b/src/main/java/de/pixart/messenger/services/MessageSearchTask.java new file mode 100644 index 000000000..4911eff75 --- /dev/null +++ b/src/main/java/de/pixart/messenger/services/MessageSearchTask.java @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2018, Daniel Gultsch All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package de.pixart.messenger.services; + +import android.database.Cursor; +import android.os.SystemClock; +import android.util.Log; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import de.pixart.messenger.Config; +import de.pixart.messenger.entities.Account; +import de.pixart.messenger.entities.Conversation; +import de.pixart.messenger.entities.Conversational; +import de.pixart.messenger.entities.IndividualMessage; +import de.pixart.messenger.entities.Message; +import de.pixart.messenger.entities.StubConversation; +import de.pixart.messenger.ui.interfaces.OnSearchResultsAvailable; +import de.pixart.messenger.utils.Cancellable; +import de.pixart.messenger.utils.ReplacingSerialSingleThreadExecutor; +import rocks.xmpp.addr.Jid; + +public class MessageSearchTask implements Runnable, Cancellable { + + private static final ReplacingSerialSingleThreadExecutor EXECUTOR = new ReplacingSerialSingleThreadExecutor(MessageSearchTask.class.getName()); + + private final XmppConnectionService xmppConnectionService; + private final String term; + private final OnSearchResultsAvailable onSearchResultsAvailable; + + private boolean isCancelled = false; + + private MessageSearchTask(XmppConnectionService xmppConnectionService, String term, OnSearchResultsAvailable onSearchResultsAvailable) { + this.xmppConnectionService = xmppConnectionService; + this.term = term; + this.onSearchResultsAvailable = onSearchResultsAvailable; + } + + public static void search(XmppConnectionService xmppConnectionService, String term, OnSearchResultsAvailable onSearchResultsAvailable) { + new MessageSearchTask(xmppConnectionService, term, onSearchResultsAvailable).executeInBackground(); + } + + @Override + public void cancel() { + this.isCancelled = true; + } + + @Override + public void run() { + long startTimestamp = SystemClock.elapsedRealtime(); + Cursor cursor = null; + try { + final HashMap<String, Conversational> conversationCache = new HashMap<>(); + final List<Message> result = new ArrayList<>(); + cursor = xmppConnectionService.databaseBackend.getMessageSearchCursor(term); + while (cursor.moveToNext()) { + final String conversationUuid = cursor.getString(cursor.getColumnIndex(Message.CONVERSATION)); + Conversational conversation; + if (conversationCache.containsKey(conversationUuid)) { + conversation = conversationCache.get(conversationUuid); + } else { + String accountUuid = cursor.getString(cursor.getColumnIndex(Conversation.ACCOUNT)); + String contactJid = cursor.getString(cursor.getColumnIndex(Conversation.CONTACTJID)); + int mode = cursor.getInt(cursor.getColumnIndex(Conversation.MODE)); + conversation = findOrGenerateStub(conversationUuid, accountUuid, contactJid, mode); + conversationCache.put(conversationUuid, conversation); + } + Message message = IndividualMessage.fromCursor(cursor, conversation); + result.add(message); + } + long stopTimestamp = SystemClock.elapsedRealtime(); + Log.d(Config.LOGTAG, "found " + result.size() + " messages in " + (stopTimestamp - startTimestamp) + "ms"); + onSearchResultsAvailable.onSearchResultsAvailable(term, result); + } catch (Exception e) { + Log.d(Config.LOGTAG, "exception while searching ", e); + } finally { + if (cursor != null) { + cursor.close(); + } + } + } + + private Conversational findOrGenerateStub(String conversationUuid, String accountUuid, String contactJid, int mode) throws Exception { + Conversation conversation = xmppConnectionService.findConversationByUuid(conversationUuid); + if (conversation != null) { + return conversation; + } + Account account = xmppConnectionService.findAccountByUuid(accountUuid); + Jid jid = Jid.of(contactJid); + if (account != null && jid != null) { + return new StubConversation(account, conversationUuid, jid.asBareJid(), mode); + } + throw new Exception("Unable to generate stub for " + contactJid); + } + + private void executeInBackground() { + EXECUTOR.execute(this); + } +}
\ No newline at end of file |