Moves Channel to LargeCache

Fixes filter for Chat Messages in discovery
This commit is contained in:
Vitor Pamplona 2024-03-23 17:21:02 -04:00
parent 0b40b6d1d8
commit 9990f458bf
3 changed files with 57 additions and 38 deletions

View File

@ -129,7 +129,7 @@ object LocalCache {
val notes = LargeCache<HexKey, Note>() val notes = LargeCache<HexKey, Note>()
val addressables = LargeCache<String, AddressableNote>() val addressables = LargeCache<String, AddressableNote>()
val channels = ConcurrentHashMap<HexKey, Channel>() val channels = LargeCache<HexKey, Channel>()
val awaitingPaymentRequests = ConcurrentHashMap<HexKey, Pair<Note?, (LnZapPaymentResponseEvent) -> Unit>>(10) val awaitingPaymentRequests = ConcurrentHashMap<HexKey, Pair<Note?, (LnZapPaymentResponseEvent) -> Unit>>(10)
fun checkGetOrCreateUser(key: String): User? { fun checkGetOrCreateUser(key: String): User? {
@ -164,7 +164,7 @@ object LocalCache {
} }
fun getChannelIfExists(key: String): Channel? { fun getChannelIfExists(key: String): Channel? {
return channels[key] return channels.get(key)
} }
fun checkGetOrCreateNote(key: String): Note? { fun checkGetOrCreateNote(key: String): Note? {
@ -217,15 +217,24 @@ object LocalCache {
} }
} }
fun getOrCreateChannel(
key: String,
channelFactory: (String) -> Channel,
): Channel {
checkNotInMainThread()
return channels.getOrCreate(key, channelFactory)
}
fun checkGetOrCreateChannel(key: String): Channel? { fun checkGetOrCreateChannel(key: String): Channel? {
checkNotInMainThread() checkNotInMainThread()
if (isValidHex(key)) { if (isValidHex(key)) {
return getOrCreateChannel(key) { PublicChatChannel(key) } return channels.getOrCreate(key) { PublicChatChannel(key) }
} }
val aTag = ATag.parse(key, null) val aTag = ATag.parse(key, null)
if (aTag != null) { if (aTag != null) {
return getOrCreateChannel(aTag.toTag()) { LiveActivitiesChannel(aTag) } return channels.getOrCreate(aTag.toTag()) { LiveActivitiesChannel(aTag) }
} }
return null return null
} }
@ -237,19 +246,6 @@ object LocalCache {
return HexValidator.isHex(key) return HexValidator.isHex(key)
} }
fun getOrCreateChannel(
key: String,
channelFactory: (String) -> Channel,
): Channel {
checkNotInMainThread()
return channels[key]
?: run {
val newObject = channelFactory(key)
channels.putIfAbsent(key, newObject) ?: newObject
}
}
fun checkGetOrCreateAddressableNote(key: String): AddressableNote? { fun checkGetOrCreateAddressableNote(key: String): AddressableNote? {
return try { return try {
val addr = ATag.parse(key, null) // relay doesn't matter for the index. val addr = ATag.parse(key, null) // relay doesn't matter for the index.
@ -941,10 +937,10 @@ object LocalCache {
masterNote.removeReport(deleteNote) masterNote.removeReport(deleteNote)
} }
deleteNote.channelHex()?.let { channels[it]?.removeNote(deleteNote) } deleteNote.channelHex()?.let { getChannelIfExists(it)?.removeNote(deleteNote) }
(deleteNote.event as? LiveActivitiesChatMessageEvent)?.activity()?.let { (deleteNote.event as? LiveActivitiesChatMessageEvent)?.activity()?.let {
channels[it.toTag()]?.removeNote(deleteNote) getChannelIfExists(it.toTag())?.removeNote(deleteNote)
} }
if (deleteNote.event is PrivateDmEvent) { if (deleteNote.event is PrivateDmEvent) {
@ -1681,14 +1677,14 @@ object LocalCache {
checkNotInMainThread() checkNotInMainThread()
val key = decodeEventIdAsHexOrNull(text) val key = decodeEventIdAsHexOrNull(text)
if (key != null && channels[key] != null) { if (key != null && getChannelIfExists(key) != null) {
return listOfNotNull(channels[key]) return listOfNotNull(getChannelIfExists(key))
} }
return channels.values.filter { return channels.filter { _, channel ->
it.anyNameStartsWith(text) || channel.anyNameStartsWith(text) ||
it.idHex.startsWith(text, true) || channel.idHex.startsWith(text, true) ||
it.idNote().startsWith(text, true) channel.idNote().startsWith(text, true)
} }
} }
@ -1767,8 +1763,8 @@ object LocalCache {
fun pruneOldAndHiddenMessages(account: Account) { fun pruneOldAndHiddenMessages(account: Account) {
checkNotInMainThread() checkNotInMainThread()
channels.forEach { it -> channels.forEach { _, channel ->
val toBeRemoved = it.value.pruneOldAndHiddenMessages(account) val toBeRemoved = channel.pruneOldAndHiddenMessages(account)
val childrenToBeRemoved = mutableListOf<Note>() val childrenToBeRemoved = mutableListOf<Note>()
@ -1780,9 +1776,9 @@ object LocalCache {
removeFromCache(childrenToBeRemoved) removeFromCache(childrenToBeRemoved)
if (toBeRemoved.size > 100 || it.value.notes.size() > 100) { if (toBeRemoved.size > 100 || channel.notes.size() > 100) {
println( println(
"PRUNE: ${toBeRemoved.size} messages removed from ${it.value.toBestDisplayName()}. ${it.value.notes.size()} kept", "PRUNE: ${toBeRemoved.size} messages removed from ${channel.toBestDisplayName()}. ${channel.notes.size()} kept",
) )
} }
} }

View File

@ -23,7 +23,7 @@ package com.vitorpamplona.amethyst.ui.dal
import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.Account
import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.LocalCache
import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.Note
import com.vitorpamplona.amethyst.model.ParticipantListBuilder import com.vitorpamplona.amethyst.model.PublicChatChannel
import com.vitorpamplona.quartz.events.ChannelCreateEvent import com.vitorpamplona.quartz.events.ChannelCreateEvent
import com.vitorpamplona.quartz.events.IsInPublicChatChannel import com.vitorpamplona.quartz.events.IsInPublicChatChannel
import com.vitorpamplona.quartz.events.MuteListEvent import com.vitorpamplona.quartz.events.MuteListEvent
@ -42,12 +42,25 @@ open class DiscoverChatFeedFilter(val account: Account) : AdditiveFeedFilter<Not
} }
override fun feed(): List<Note> { override fun feed(): List<Note> {
val params = buildFilterParams(account)
val allChannelNotes = val allChannelNotes =
LocalCache.channels.values.mapNotNull { LocalCache.getNoteIfExists(it.idHex) } LocalCache.channels.mapNotNullIntoSet { _, channel ->
if (channel is PublicChatChannel) {
val note = LocalCache.getNoteIfExists(channel.idHex)
val noteEvent = note?.event
val notes = innerApplyFilter(allChannelNotes) if (noteEvent == null || params.match(noteEvent)) {
note
} else {
null
}
} else {
null
}
}
return sort(notes) return sort(allChannelNotes)
} }
override fun applyFilter(collection: Set<Note>): Set<Note> { override fun applyFilter(collection: Set<Note>): Set<Note> {
@ -70,11 +83,21 @@ open class DiscoverChatFeedFilter(val account: Account) : AdditiveFeedFilter<Not
// note event here will never be null // note event here will never be null
val noteEvent = note.event val noteEvent = note.event
if (noteEvent is ChannelCreateEvent && params.match(noteEvent)) { if (noteEvent is ChannelCreateEvent && params.match(noteEvent)) {
note if ((LocalCache.getChannelIfExists(noteEvent.id)?.notes?.size() ?: 0) > 0) {
note
} else {
null
}
} else if (noteEvent is IsInPublicChatChannel) { } else if (noteEvent is IsInPublicChatChannel) {
val channel = noteEvent.channel()?.let { LocalCache.checkGetOrCreateNote(it) } val channel = noteEvent.channel()?.let { LocalCache.checkGetOrCreateNote(it) }
if (channel != null && (channel.event == null || params.match(channel.event))) { if (channel != null &&
channel (channel.event == null || (channel.event is ChannelCreateEvent && params.match(channel.event)))
) {
if ((LocalCache.getChannelIfExists(channel.idHex)?.notes?.size() ?: 0) > 0) {
channel
} else {
null
}
} else { } else {
null null
} }

View File

@ -48,8 +48,8 @@ open class DiscoverLiveFeedFilter(
} }
override fun feed(): List<Note> { override fun feed(): List<Note> {
val allChannelNotes = LocalCache.channels.values.mapNotNull { LocalCache.getNoteIfExists(it.idHex) } val allChannelNotes = LocalCache.channels.mapNotNull { _, channel -> LocalCache.getNoteIfExists(channel.idHex) }
val allMessageNotes = LocalCache.channels.values.map { it.notes.filter { key, it -> it.event is LiveActivitiesEvent } }.flatten() val allMessageNotes = LocalCache.channels.map { _, channel -> channel.notes.filter { key, it -> it.event is LiveActivitiesEvent } }.flatten()
val notes = innerApplyFilter(allChannelNotes + allMessageNotes) val notes = innerApplyFilter(allChannelNotes + allMessageNotes)