From dfe5f86a23af543d66175e7d73cd36068880c470 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Thu, 14 Aug 2025 11:28:03 -0400 Subject: [PATCH] Faster PublishedAt providers --- .../com/vitorpamplona/amethyst/model/Note.kt | 19 +++----------- .../tags/publishedAt/PublishedAtProvider.kt | 25 +++++++++++++++++++ .../nip23LongContent/LongTextNoteEvent.kt | 4 ++- .../quartz/nip54Wiki/WikiNoteEvent.kt | 4 ++- .../quartz/nip71Video/VideoEvent.kt | 4 ++- .../definition/AppDefinitionEvent.kt | 6 +++-- .../nip99Classifieds/ClassifiedsEvent.kt | 6 +++-- 7 files changed, 45 insertions(+), 23 deletions(-) create mode 100644 quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/tags/publishedAt/PublishedAtProvider.kt diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Note.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Note.kt index e23666235..4fe1c0b60 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Note.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Note.kt @@ -41,6 +41,7 @@ import com.vitorpamplona.quartz.nip01Core.tags.addressables.Address import com.vitorpamplona.quartz.nip01Core.tags.events.ETag import com.vitorpamplona.quartz.nip01Core.tags.events.EventReference import com.vitorpamplona.quartz.nip01Core.tags.hashtags.anyHashTag +import com.vitorpamplona.quartz.nip01Core.tags.publishedAt.PublishedAtProvider import com.vitorpamplona.quartz.nip02FollowList.ImmutableListOfLists import com.vitorpamplona.quartz.nip10Notes.BaseThreadedEvent import com.vitorpamplona.quartz.nip10Notes.tags.MarkedETag @@ -49,7 +50,6 @@ import com.vitorpamplona.quartz.nip18Reposts.RepostEvent import com.vitorpamplona.quartz.nip19Bech32.entities.NAddress import com.vitorpamplona.quartz.nip19Bech32.entities.NEvent import com.vitorpamplona.quartz.nip22Comments.CommentEvent -import com.vitorpamplona.quartz.nip23LongContent.LongTextNoteEvent import com.vitorpamplona.quartz.nip28PublicChat.message.ChannelMessageEvent import com.vitorpamplona.quartz.nip36SensitiveContent.isSensitiveOrNSFW import com.vitorpamplona.quartz.nip37Drafts.DraftWrapEvent @@ -58,15 +58,12 @@ import com.vitorpamplona.quartz.nip47WalletConnect.LnZapPaymentResponseEvent import com.vitorpamplona.quartz.nip47WalletConnect.PayInvoiceMethod import com.vitorpamplona.quartz.nip47WalletConnect.PayInvoiceSuccessResponse import com.vitorpamplona.quartz.nip53LiveActivities.chat.LiveActivitiesChatMessageEvent -import com.vitorpamplona.quartz.nip54Wiki.WikiNoteEvent import com.vitorpamplona.quartz.nip56Reports.ReportEvent import com.vitorpamplona.quartz.nip56Reports.ReportType import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent import com.vitorpamplona.quartz.nip57Zaps.LnZapRequestEvent import com.vitorpamplona.quartz.nip59Giftwrap.WrappedEvent -import com.vitorpamplona.quartz.nip71Video.VideoEvent import com.vitorpamplona.quartz.nip72ModCommunities.approval.CommunityPostApprovalEvent -import com.vitorpamplona.quartz.nip99Classifieds.ClassifiedsEvent import com.vitorpamplona.quartz.utils.TimeUtils import com.vitorpamplona.quartz.utils.anyAsync import com.vitorpamplona.quartz.utils.containsAny @@ -95,19 +92,9 @@ class AddressableNote( override fun createdAt(): Long? { val currentEvent = event - if (currentEvent == null) return null - - val publishedAt = - when (currentEvent) { - is LongTextNoteEvent -> currentEvent.publishedAt() ?: Long.MAX_VALUE - is WikiNoteEvent -> currentEvent.publishedAt() ?: Long.MAX_VALUE - is VideoEvent -> currentEvent.publishedAt() ?: Long.MAX_VALUE - is ClassifiedsEvent -> currentEvent.publishedAt() ?: Long.MAX_VALUE - else -> Long.MAX_VALUE - } - - return minOf(publishedAt, currentEvent.createdAt) + if (currentEvent is PublishedAtProvider) return currentEvent.publishedAt() ?: currentEvent.createdAt + return currentEvent.createdAt } fun dTag(): String = address.dTag diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/tags/publishedAt/PublishedAtProvider.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/tags/publishedAt/PublishedAtProvider.kt new file mode 100644 index 000000000..d16102f72 --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/tags/publishedAt/PublishedAtProvider.kt @@ -0,0 +1,25 @@ +/** + * Copyright (c) 2025 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip01Core.tags.publishedAt + +interface PublishedAtProvider { + fun publishedAt(): Long? +} diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip23LongContent/LongTextNoteEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip23LongContent/LongTextNoteEvent.kt index 23b131b0b..f561afb53 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/nip23LongContent/LongTextNoteEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip23LongContent/LongTextNoteEvent.kt @@ -37,6 +37,7 @@ import com.vitorpamplona.quartz.nip01Core.tags.addressables.Address import com.vitorpamplona.quartz.nip01Core.tags.dTags.dTag import com.vitorpamplona.quartz.nip01Core.tags.hashtags.hashtags import com.vitorpamplona.quartz.nip01Core.tags.people.PTag +import com.vitorpamplona.quartz.nip01Core.tags.publishedAt.PublishedAtProvider import com.vitorpamplona.quartz.nip10Notes.BaseThreadedEvent import com.vitorpamplona.quartz.nip18Reposts.quotes.QTag import com.vitorpamplona.quartz.nip19Bech32.addressHints @@ -68,6 +69,7 @@ class LongTextNoteEvent( EventHintProvider, PubKeyHintProvider, AddressHintProvider, + PublishedAtProvider, RootScope, SearchableEvent { override fun indexableContent() = "title: " + title() + "\nsummary: " + summary() + "\n" + content @@ -130,7 +132,7 @@ class LongTextNoteEvent( fun summary() = tags.firstNotNullOfOrNull(SummaryTag::parse) - fun publishedAt() = tags.firstNotNullOfOrNull(PublishedAtTag::parse) + override fun publishedAt() = tags.firstNotNullOfOrNull(PublishedAtTag::parse) companion object { const val KIND = 30023 diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip54Wiki/WikiNoteEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip54Wiki/WikiNoteEvent.kt index d0996a1fc..e35cbafef 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/nip54Wiki/WikiNoteEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip54Wiki/WikiNoteEvent.kt @@ -36,6 +36,7 @@ import com.vitorpamplona.quartz.nip01Core.tags.addressables.Address import com.vitorpamplona.quartz.nip01Core.tags.dTags.dTag import com.vitorpamplona.quartz.nip01Core.tags.hashtags.hashtags import com.vitorpamplona.quartz.nip01Core.tags.people.PTag +import com.vitorpamplona.quartz.nip01Core.tags.publishedAt.PublishedAtProvider import com.vitorpamplona.quartz.nip10Notes.BaseThreadedEvent import com.vitorpamplona.quartz.nip10Notes.tags.MarkedETag import com.vitorpamplona.quartz.nip18Reposts.quotes.QTag @@ -62,6 +63,7 @@ class WikiNoteEvent( EventHintProvider, AddressHintProvider, PubKeyHintProvider, + PublishedAtProvider, SearchableEvent { override fun indexableContent() = "title: " + title() + "\nsummary: " + summary() + "\n" + content @@ -127,7 +129,7 @@ class WikiNoteEvent( fun image() = tags.firstOrNull { it.size > 1 && it[0] == "image" }?.get(1) - fun publishedAt() = + override fun publishedAt() = try { tags.firstOrNull { it.size > 1 && it[0] == "published_at" }?.get(1)?.toLongOrNull() } catch (_: Exception) { diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip71Video/VideoEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip71Video/VideoEvent.kt index 2d2b61cc9..71ec35c8c 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/nip71Video/VideoEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip71Video/VideoEvent.kt @@ -26,6 +26,7 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.tags.events.ETag import com.vitorpamplona.quartz.nip01Core.tags.hashtags.hashtags import com.vitorpamplona.quartz.nip01Core.tags.people.PTag +import com.vitorpamplona.quartz.nip01Core.tags.publishedAt.PublishedAtProvider import com.vitorpamplona.quartz.nip22Comments.RootScope import com.vitorpamplona.quartz.nip23LongContent.tags.PublishedAtTag import com.vitorpamplona.quartz.nip23LongContent.tags.TitleTag @@ -45,12 +46,13 @@ abstract class VideoEvent( content: String, sig: HexKey, ) : BaseAddressableEvent(id, pubKey, createdAt, kind, tags, content, sig), + PublishedAtProvider, RootScope { @Transient var iMetas: List? = null fun title() = tags.firstNotNullOfOrNull(TitleTag::parse) - fun publishedAt() = tags.firstNotNullOfOrNull(PublishedAtTag::parse) + override fun publishedAt() = tags.firstNotNullOfOrNull(PublishedAtTag::parse) fun duration() = tags.firstNotNullOfOrNull(DurationTag::parse) diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip89AppHandlers/definition/AppDefinitionEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip89AppHandlers/definition/AppDefinitionEvent.kt index f2d77522e..76db75a2a 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/nip89AppHandlers/definition/AppDefinitionEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip89AppHandlers/definition/AppDefinitionEvent.kt @@ -29,6 +29,7 @@ import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.dTags.dTag import com.vitorpamplona.quartz.nip01Core.tags.kinds.isTaggedKind import com.vitorpamplona.quartz.nip01Core.tags.kinds.kinds +import com.vitorpamplona.quartz.nip01Core.tags.publishedAt.PublishedAtProvider import com.vitorpamplona.quartz.nip21UriScheme.toNostrUri import com.vitorpamplona.quartz.nip23LongContent.tags.PublishedAtTag import com.vitorpamplona.quartz.nip31Alts.alt @@ -46,7 +47,8 @@ class AppDefinitionEvent( tags: Array>, content: String, sig: HexKey, -) : BaseAddressableEvent(id, pubKey, createdAt, KIND, tags, content, sig) { +) : BaseAddressableEvent(id, pubKey, createdAt, KIND, tags, content, sig), + PublishedAtProvider { override fun countMemory(): Long = super.countMemory() + (cachedMetadata?.countMemory() ?: 8L) @Transient private var cachedMetadata: AppMetadata? = null @@ -77,7 +79,7 @@ class AppDefinitionEvent( fun includeKind(kind: Int) = tags.isTaggedKind(kind) - fun publishedAt() = tags.firstNotNullOfOrNull(PublishedAtTag::parse) + override fun publishedAt() = tags.firstNotNullOfOrNull(PublishedAtTag::parse) companion object { const val KIND = 31990 diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip99Classifieds/ClassifiedsEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip99Classifieds/ClassifiedsEvent.kt index 0de755531..b0222fca9 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/nip99Classifieds/ClassifiedsEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip99Classifieds/ClassifiedsEvent.kt @@ -28,6 +28,7 @@ import com.vitorpamplona.quartz.nip01Core.core.containsAllTagNamesWithValues import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.dTags.dTag import com.vitorpamplona.quartz.nip01Core.tags.hashtags.hashtags +import com.vitorpamplona.quartz.nip01Core.tags.publishedAt.PublishedAtProvider import com.vitorpamplona.quartz.nip23LongContent.tags.ImageTag import com.vitorpamplona.quartz.nip23LongContent.tags.PublishedAtTag import com.vitorpamplona.quartz.nip23LongContent.tags.SummaryTag @@ -49,7 +50,8 @@ class ClassifiedsEvent( tags: Array>, content: String, sig: HexKey, -) : BaseAddressableEvent(id, pubKey, createdAt, KIND, tags, content, sig) { +) : BaseAddressableEvent(id, pubKey, createdAt, KIND, tags, content, sig), + PublishedAtProvider { fun title() = tags.firstNotNullOfOrNull(TitleTag::parse) fun image() = tags.firstNotNullOfOrNull(ImageTag::parse) @@ -68,7 +70,7 @@ class ClassifiedsEvent( fun location() = tags.firstNotNullOfOrNull(LocationTag::parse) - fun publishedAt() = tags.firstNotNullOfOrNull(PublishedAtTag::parse) + override fun publishedAt() = tags.firstNotNullOfOrNull(PublishedAtTag::parse) fun categories() = tags.hashtags()