mirror of
https://github.com/oxen-io/session-android.git
synced 2025-02-17 13:58:25 +00:00
Replace LinkedHashMap with a SoftReference LRUCache. Add Slide cache.
This commit is contained in:
parent
a362c8755a
commit
50fae64330
@ -31,9 +31,11 @@ import org.thoughtcrime.securesms.database.MmsSmsColumns;
|
||||
import org.thoughtcrime.securesms.database.MmsSmsDatabase;
|
||||
import org.thoughtcrime.securesms.database.SmsDatabase;
|
||||
import org.thoughtcrime.securesms.database.model.MessageRecord;
|
||||
import org.thoughtcrime.securesms.recipients.Recipients;
|
||||
import org.thoughtcrime.securesms.util.LRUCache;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A cursor adapter for a conversation thread. Ultimately
|
||||
@ -46,8 +48,9 @@ import java.util.LinkedHashMap;
|
||||
public class ConversationAdapter extends CursorAdapter implements AbsListView.RecyclerListener {
|
||||
|
||||
private static final int MAX_CACHE_SIZE = 40;
|
||||
private final Map<String,SoftReference<MessageRecord>> messageRecordCache =
|
||||
Collections.synchronizedMap(new LRUCache<String, SoftReference<MessageRecord>>(MAX_CACHE_SIZE));
|
||||
|
||||
private final LinkedHashMap<String,MessageRecord> messageRecordCache;
|
||||
private final Handler failedIconClickHandler;
|
||||
private final Context context;
|
||||
private final MasterSecret masterSecret;
|
||||
@ -62,7 +65,6 @@ public class ConversationAdapter extends CursorAdapter implements AbsListView.Re
|
||||
this.masterSecret = masterSecret;
|
||||
this.failedIconClickHandler = failedIconClickHandler;
|
||||
this.groupThread = groupThread;
|
||||
this.messageRecordCache = initializeCache();
|
||||
this.inflater = (LayoutInflater)context
|
||||
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
}
|
||||
@ -111,14 +113,22 @@ public class ConversationAdapter extends CursorAdapter implements AbsListView.Re
|
||||
}
|
||||
|
||||
private MessageRecord getMessageRecord(long messageId, Cursor cursor, String type) {
|
||||
if (messageRecordCache.containsKey(type + messageId))
|
||||
return messageRecordCache.get(type + messageId);
|
||||
SoftReference<MessageRecord> reference = messageRecordCache.get(type + messageId);
|
||||
|
||||
MmsSmsDatabase.Reader reader = DatabaseFactory.getMmsSmsDatabase(context).readerFor(cursor, masterSecret);
|
||||
if (reference != null) {
|
||||
MessageRecord record = reference.get();
|
||||
|
||||
if (record != null)
|
||||
return record;
|
||||
}
|
||||
|
||||
MmsSmsDatabase.Reader reader = DatabaseFactory.getMmsSmsDatabase(context)
|
||||
.readerFor(cursor, masterSecret);
|
||||
|
||||
MessageRecord messageRecord = reader.getCurrent();
|
||||
|
||||
messageRecordCache.put(type + messageId, messageRecord);
|
||||
messageRecordCache.put(type + messageId, new SoftReference<MessageRecord>(messageRecord));
|
||||
|
||||
return messageRecord;
|
||||
}
|
||||
|
||||
@ -136,13 +146,4 @@ public class ConversationAdapter extends CursorAdapter implements AbsListView.Re
|
||||
public void onMovedToScrapHeap(View view) {
|
||||
((ConversationItem)view).unbind();
|
||||
}
|
||||
|
||||
private LinkedHashMap<String,MessageRecord> initializeCache() {
|
||||
return new LinkedHashMap<String,MessageRecord>() {
|
||||
@Override
|
||||
protected boolean removeEldestEntry(Entry<String,MessageRecord> eldest) {
|
||||
return this.size() > MAX_CACHE_SIZE;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -30,10 +30,12 @@ import org.thoughtcrime.securesms.database.model.DisplayRecord;
|
||||
import org.thoughtcrime.securesms.sms.IncomingTextMessage;
|
||||
import org.thoughtcrime.securesms.sms.OutgoingTextMessage;
|
||||
import org.thoughtcrime.securesms.util.InvalidMessageException;
|
||||
import org.thoughtcrime.securesms.util.LRUCache;
|
||||
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class EncryptingSmsDatabase extends SmsDatabase {
|
||||
|
||||
@ -156,37 +158,25 @@ public class EncryptingSmsDatabase extends SmsDatabase {
|
||||
|
||||
private static class PlaintextCache {
|
||||
private static final int MAX_CACHE_SIZE = 2000;
|
||||
|
||||
private static final LinkedHashMap<String,SoftReference<String>> decryptedBodyCache
|
||||
= new LinkedHashMap<String,SoftReference<String>>()
|
||||
{
|
||||
@Override
|
||||
protected boolean removeEldestEntry(Entry<String,SoftReference<String>> eldest) {
|
||||
return this.size() > MAX_CACHE_SIZE;
|
||||
}
|
||||
};
|
||||
private static final Map<String, SoftReference<String>> decryptedBodyCache =
|
||||
Collections.synchronizedMap(new LRUCache<String, SoftReference<String>>(MAX_CACHE_SIZE));
|
||||
|
||||
public void put(String ciphertext, String plaintext) {
|
||||
decryptedBodyCache.put(ciphertext, new SoftReference<String>(plaintext));
|
||||
}
|
||||
|
||||
public String get(String ciphertext) {
|
||||
synchronized (decryptedBodyCache) {
|
||||
SoftReference<String> plaintextReference = decryptedBodyCache.get(ciphertext);
|
||||
SoftReference<String> plaintextReference = decryptedBodyCache.get(ciphertext);
|
||||
|
||||
if (plaintextReference != null) {
|
||||
String plaintext = plaintextReference.get();
|
||||
if (plaintextReference != null) {
|
||||
String plaintext = plaintextReference.get();
|
||||
|
||||
if (plaintext != null) {
|
||||
return plaintext;
|
||||
} else {
|
||||
decryptedBodyCache.remove(ciphertext);
|
||||
return null;
|
||||
}
|
||||
if (plaintext != null) {
|
||||
return plaintext;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -41,12 +41,16 @@ import org.thoughtcrime.securesms.recipients.RecipientFactory;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientFormattingException;
|
||||
import org.thoughtcrime.securesms.recipients.Recipients;
|
||||
import org.thoughtcrime.securesms.util.InvalidMessageException;
|
||||
import org.thoughtcrime.securesms.util.LRUCache;
|
||||
import org.thoughtcrime.securesms.util.ListenableFutureTask;
|
||||
import org.thoughtcrime.securesms.util.Trimmer;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
@ -130,6 +134,8 @@ public class MmsDatabase extends Database implements MmsSmsColumns {
|
||||
};
|
||||
|
||||
public static final ExecutorService slideResolver = Util.newSingleThreadedLifoExecutor();
|
||||
private static final Map<Long, SoftReference<SlideDeck>> slideCache =
|
||||
Collections.synchronizedMap(new LRUCache<Long, SoftReference<SlideDeck>>(20));
|
||||
|
||||
public MmsDatabase(Context context, SQLiteOpenHelper databaseHelper) {
|
||||
super(context, databaseHelper);
|
||||
@ -801,6 +807,12 @@ public class MmsDatabase extends Database implements MmsSmsColumns {
|
||||
private ListenableFutureTask<SlideDeck> getSlideDeck(final MasterSecret masterSecret,
|
||||
final long id)
|
||||
{
|
||||
ListenableFutureTask<SlideDeck> future = getCachedSlideDeck(id);
|
||||
|
||||
if (future != null) {
|
||||
return future;
|
||||
}
|
||||
|
||||
Callable<SlideDeck> task = new Callable<SlideDeck>() {
|
||||
@Override
|
||||
public SlideDeck call() throws Exception {
|
||||
@ -808,16 +820,43 @@ public class MmsDatabase extends Database implements MmsSmsColumns {
|
||||
return null;
|
||||
|
||||
PduBody body = getPartDatabase(masterSecret).getParts(id, false);
|
||||
return new SlideDeck(context, masterSecret, body);
|
||||
SlideDeck slideDeck = new SlideDeck(context, masterSecret, body);
|
||||
slideCache.put(id, new SoftReference<SlideDeck>(slideDeck));
|
||||
|
||||
return slideDeck;
|
||||
}
|
||||
};
|
||||
|
||||
ListenableFutureTask<SlideDeck> future = new ListenableFutureTask<SlideDeck>(task, null);
|
||||
future = new ListenableFutureTask<SlideDeck>(task, null);
|
||||
slideResolver.execute(future);
|
||||
|
||||
return future;
|
||||
}
|
||||
|
||||
private ListenableFutureTask<SlideDeck> getCachedSlideDeck(final long id) {
|
||||
SoftReference<SlideDeck> reference = slideCache.get(id);
|
||||
|
||||
if (reference != null) {
|
||||
final SlideDeck slideDeck = reference.get();
|
||||
|
||||
if (slideDeck != null) {
|
||||
Callable<SlideDeck> task = new Callable<SlideDeck>() {
|
||||
@Override
|
||||
public SlideDeck call() throws Exception {
|
||||
return slideDeck;
|
||||
}
|
||||
};
|
||||
|
||||
ListenableFutureTask<SlideDeck> future = new ListenableFutureTask<SlideDeck>(task, null);
|
||||
future.run();
|
||||
|
||||
return future;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void close() {
|
||||
cursor.close();
|
||||
}
|
||||
|
@ -33,13 +33,15 @@ import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||
import org.thoughtcrime.securesms.database.MmsDatabase;
|
||||
import org.thoughtcrime.securesms.util.BitmapUtil;
|
||||
import org.thoughtcrime.securesms.util.LRUCache;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import ws.com.google.android.mms.ContentType;
|
||||
import ws.com.google.android.mms.pdu.PduPart;
|
||||
@ -47,13 +49,8 @@ import ws.com.google.android.mms.pdu.PduPart;
|
||||
public class ImageSlide extends Slide {
|
||||
|
||||
private static final int MAX_CACHE_SIZE = 10;
|
||||
|
||||
private static final LinkedHashMap<Uri,SoftReference<Bitmap>> thumbnailCache = new LinkedHashMap<Uri,SoftReference<Bitmap>>() {
|
||||
@Override
|
||||
protected boolean removeEldestEntry(Entry<Uri,SoftReference<Bitmap>> eldest) {
|
||||
return this.size() > MAX_CACHE_SIZE;
|
||||
}
|
||||
};
|
||||
private static final Map<Uri, SoftReference<Bitmap>> thumbnailCache =
|
||||
Collections.synchronizedMap(new LRUCache<Uri, SoftReference<Bitmap>>(MAX_CACHE_SIZE));
|
||||
|
||||
public ImageSlide(Context context, MasterSecret masterSecret, PduPart part) {
|
||||
super(context, masterSecret, part);
|
||||
|
@ -16,30 +16,28 @@
|
||||
*/
|
||||
package org.thoughtcrime.securesms.mms;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||
|
||||
import ws.com.google.android.mms.ContentType;
|
||||
import ws.com.google.android.mms.pdu.CharacterSets;
|
||||
import ws.com.google.android.mms.pdu.PduPart;
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.util.Log;
|
||||
|
||||
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||
import org.thoughtcrime.securesms.util.LRUCache;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import ws.com.google.android.mms.ContentType;
|
||||
import ws.com.google.android.mms.pdu.CharacterSets;
|
||||
import ws.com.google.android.mms.pdu.PduPart;
|
||||
|
||||
public class TextSlide extends Slide {
|
||||
|
||||
private static final int MAX_CACHE_SIZE = 10;
|
||||
|
||||
private static final LinkedHashMap<Uri,String> textCache = new LinkedHashMap<Uri,String>() {
|
||||
@Override
|
||||
protected boolean removeEldestEntry(Entry<Uri,String> eldest) {
|
||||
return this.size() > MAX_CACHE_SIZE;
|
||||
}
|
||||
};
|
||||
|
||||
private static final Map<Uri, SoftReference<String>> textCache =
|
||||
Collections.synchronizedMap(new LRUCache<Uri, SoftReference<String>>(MAX_CACHE_SIZE));
|
||||
|
||||
public TextSlide(Context context, MasterSecret masterSecret, PduPart part) {
|
||||
super(context, masterSecret, part);
|
||||
}
|
||||
@ -54,16 +52,25 @@ public class TextSlide extends Slide {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText() {
|
||||
public String getText() {
|
||||
try {
|
||||
if (textCache.containsKey(part.getDataUri()))
|
||||
return textCache.get(part.getDataUri());
|
||||
|
||||
SoftReference<String> reference = textCache.get(part.getDataUri());
|
||||
|
||||
if (reference != null) {
|
||||
String cachedText = reference.get();
|
||||
|
||||
if (cachedText != null) {
|
||||
return cachedText;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
String text = new String(getPartData(), CharacterSets.getMimeName(part.getCharset()));
|
||||
textCache.put(part.getDataUri(), text);
|
||||
textCache.put(part.getDataUri(), new SoftReference<String>(text));
|
||||
|
||||
return text;
|
||||
} catch (UnsupportedEncodingException uee) {
|
||||
Log.w("TextSlide", uee);
|
||||
return new String(getPartData());
|
||||
}
|
||||
}
|
||||
@ -75,7 +82,7 @@ public class TextSlide extends Slide {
|
||||
part.setData(message.getBytes(CharacterSets.MIMENAME_ISO_8859_1));
|
||||
|
||||
if (part.getData().length == 0)
|
||||
throw new AssertionError("Part data should not be zero!");
|
||||
throw new AssertionError("Part data should not be zero!");
|
||||
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
Log.w("TextSlide", "ISO_8859_1 must be supported!", e);
|
||||
@ -89,5 +96,4 @@ public class TextSlide extends Slide {
|
||||
|
||||
return part;
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user