From 67202c32d41f9c95d184c72c18f3214bc6cda4ac Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Thu, 21 Mar 2024 08:51:23 -0400 Subject: [PATCH] Migrates channel notes to LargeCache --- .../vitorpamplona/amethyst/model/Channel.kt | 21 ++++++++++--------- .../amethyst/model/LocalCache.kt | 4 ++-- .../com/vitorpamplona/amethyst/model/Note.kt | 3 ++- .../amethyst/model/ParticipantListBuilder.kt | 2 +- .../amethyst/ui/dal/ChannelFeedFilter.kt | 9 ++++---- .../ui/dal/ChatroomListKnownFeedFilter.kt | 11 ++++------ .../amethyst/ui/dal/DiscoverLiveFeedFilter.kt | 5 ++--- .../amethyst/commons/data/LargeCache.kt | 11 ++++++++++ 8 files changed, 38 insertions(+), 28 deletions(-) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/model/Channel.kt b/app/src/main/java/com/vitorpamplona/amethyst/model/Channel.kt index 4cb65397a..18865dbb4 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/model/Channel.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/model/Channel.kt @@ -22,9 +22,11 @@ package com.vitorpamplona.amethyst.model import androidx.compose.runtime.Stable import androidx.lifecycle.LiveData +import com.vitorpamplona.amethyst.commons.data.LargeCache import com.vitorpamplona.amethyst.service.NostrSingleChannelDataSource import com.vitorpamplona.amethyst.service.checkNotInMainThread import com.vitorpamplona.amethyst.ui.components.BundledUpdate +import com.vitorpamplona.amethyst.ui.dal.DefaultFeedOrder import com.vitorpamplona.amethyst.ui.note.toShortenHex import com.vitorpamplona.quartz.encoders.ATag import com.vitorpamplona.quartz.encoders.Hex @@ -33,7 +35,6 @@ import com.vitorpamplona.quartz.encoders.toNote import com.vitorpamplona.quartz.events.ChannelCreateEvent import com.vitorpamplona.quartz.events.LiveActivitiesEvent import kotlinx.coroutines.Dispatchers -import java.util.concurrent.ConcurrentHashMap @Stable class PublicChatChannel(idHex: String) : Channel(idHex) { @@ -110,7 +111,7 @@ abstract class Channel(val idHex: String) { var updatedMetadataAt: Long = 0 - val notes = ConcurrentHashMap() + val notes = LargeCache() open fun id() = Hex.decode(idHex) @@ -145,7 +146,7 @@ abstract class Channel(val idHex: String) { } fun addNote(note: Note) { - notes[note.idHex] = note + notes.put(note.idHex, note) } fun removeNote(note: Note) { @@ -163,18 +164,18 @@ abstract class Channel(val idHex: String) { fun pruneOldAndHiddenMessages(account: Account): Set { val important = - notes.values - .filter { it.author?.let { it1 -> account.isHidden(it1) } == false } - .sortedWith(compareBy({ it.createdAt() }, { it.idHex })) - .reversed() - .take(1000) + notes.filter { key, it -> + it.author?.let { author -> account.isHidden(author) } == false + } + .sortedWith(DefaultFeedOrder) + .take(500) .toSet() - val toBeRemoved = notes.values.filter { it !in important }.toSet() + val toBeRemoved = notes.filter { key, it -> it !in important } toBeRemoved.forEach { notes.remove(it.idHex) } - return toBeRemoved + return toBeRemoved.toSet() } } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt b/app/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt index acd2709d1..eb4f270c3 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt @@ -1780,9 +1780,9 @@ object LocalCache { removeFromCache(childrenToBeRemoved) - if (toBeRemoved.size > 100 || it.value.notes.size > 100) { + if (toBeRemoved.size > 100 || it.value.notes.size() > 100) { println( - "PRUNE: ${toBeRemoved.size} messages removed from ${it.value.toBestDisplayName()}. ${it.value.notes.size} kept", + "PRUNE: ${toBeRemoved.size} messages removed from ${it.value.toBestDisplayName()}. ${it.value.notes.size()} kept", ) } } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/model/Note.kt b/app/src/main/java/com/vitorpamplona/amethyst/model/Note.kt index 7f8e2e1cf..173df25de 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/model/Note.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/model/Note.kt @@ -171,7 +171,8 @@ open class Note(val idHex: String) { event is LiveActivitiesEvent ) { (event as? ChannelMessageEvent)?.channel() - ?: (event as? ChannelMetadataEvent)?.channel() ?: (event as? ChannelCreateEvent)?.id + ?: (event as? ChannelMetadataEvent)?.channel() + ?: (event as? ChannelCreateEvent)?.id ?: (event as? LiveActivitiesChatMessageEvent)?.activity()?.toTag() ?: (event as? LiveActivitiesEvent)?.address()?.toTag() } else { diff --git a/app/src/main/java/com/vitorpamplona/amethyst/model/ParticipantListBuilder.kt b/app/src/main/java/com/vitorpamplona/amethyst/model/ParticipantListBuilder.kt index db99be861..bd1ead6a3 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/model/ParticipantListBuilder.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/model/ParticipantListBuilder.kt @@ -96,7 +96,7 @@ class ParticipantListBuilder { it.replyTo?.forEach { addFollowsThatDirectlyParticipateOnToSet(it, followingSet, mySet) } } - LocalCache.getChannelIfExists(baseNote.idHex)?.notes?.values?.forEach { + LocalCache.getChannelIfExists(baseNote.idHex)?.notes?.forEach { key, it -> addFollowsThatDirectlyParticipateOnToSet(it, followingSet, mySet) } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/ChannelFeedFilter.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/ChannelFeedFilter.kt index a8a6ec236..87e113353 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/ChannelFeedFilter.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/ChannelFeedFilter.kt @@ -31,10 +31,11 @@ class ChannelFeedFilter(val channel: Channel, val account: Account) : AdditiveFe // returns the last Note of each user. override fun feed(): List { - return channel.notes.values - .filter { account.isAcceptable(it) } - .sortedWith(compareBy({ it.createdAt() }, { it.idHex })) - .reversed() + return sort( + channel.notes.filterIntoSet { key, it -> + account.isAcceptable(it) + }, + ) } override fun applyFilter(collection: Set): Set { diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/ChatroomListKnownFeedFilter.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/ChatroomListKnownFeedFilter.kt index b78716deb..2a1e6b20d 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/ChatroomListKnownFeedFilter.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/ChatroomListKnownFeedFilter.kt @@ -56,15 +56,12 @@ class ChatroomListKnownFeedFilter(val account: Account) : AdditiveFeedFilter - it.notes.values - .filter { account.isAcceptable(it) && it.event != null } - .sortedWith(compareBy({ it.createdAt() }, { it.idHex })) - .lastOrNull() + it.notes.filter { key, it -> account.isAcceptable(it) && it.event != null } + .sortedWith(DefaultFeedOrder) + .firstOrNull() } - return (privateMessages + publicChannels) - .sortedWith(compareBy({ it.createdAt() }, { it.idHex })) - .reversed() + return (privateMessages + publicChannels).sortedWith(DefaultFeedOrder) } override fun updateListWith( diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/DiscoverLiveFeedFilter.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/DiscoverLiveFeedFilter.kt index 6fc737bb8..30aa19176 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/DiscoverLiveFeedFilter.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/DiscoverLiveFeedFilter.kt @@ -48,9 +48,8 @@ open class DiscoverLiveFeedFilter( } override fun feed(): List { - val allChannelNotes = - LocalCache.channels.values.mapNotNull { LocalCache.getNoteIfExists(it.idHex) } - val allMessageNotes = LocalCache.channels.values.map { it.notes.values }.flatten() + val allChannelNotes = LocalCache.channels.values.mapNotNull { LocalCache.getNoteIfExists(it.idHex) } + val allMessageNotes = LocalCache.channels.values.map { it.notes.filter { key, it -> it.event is LiveActivitiesEvent } }.flatten() val notes = innerApplyFilter(allChannelNotes + allMessageNotes) diff --git a/commons/src/main/java/com/vitorpamplona/amethyst/commons/data/LargeCache.kt b/commons/src/main/java/com/vitorpamplona/amethyst/commons/data/LargeCache.kt index a82f35aba..444cd76e0 100644 --- a/commons/src/main/java/com/vitorpamplona/amethyst/commons/data/LargeCache.kt +++ b/commons/src/main/java/com/vitorpamplona/amethyst/commons/data/LargeCache.kt @@ -32,6 +32,17 @@ class LargeCache { fun size() = cache.size + fun isEmpty() = cache.isEmpty() + + fun containsKey(key: K) = cache.containsKey(key) + + fun put( + key: K, + value: V, + ) { + cache.put(key, value) + } + fun getOrCreate( key: K, builder: (key: K) -> V,