mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2025-11-10 21:16:46 +01:00
Improves the accuracy of the Event memory counter.
This commit is contained in:
@@ -30,14 +30,14 @@ object RelayStats {
|
|||||||
|
|
||||||
fun addBytesReceived(
|
fun addBytesReceived(
|
||||||
url: String,
|
url: String,
|
||||||
bytesUsedInMemory: Int,
|
bytesUsedInMemory: Long,
|
||||||
) {
|
) {
|
||||||
get(url).addBytesReceived(bytesUsedInMemory)
|
get(url).addBytesReceived(bytesUsedInMemory)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addBytesSent(
|
fun addBytesSent(
|
||||||
url: String,
|
url: String,
|
||||||
bytesUsedInMemory: Int,
|
bytesUsedInMemory: Long,
|
||||||
) {
|
) {
|
||||||
get(url).addBytesSent(bytesUsedInMemory)
|
get(url).addBytesSent(bytesUsedInMemory)
|
||||||
}
|
}
|
||||||
@@ -102,11 +102,11 @@ class RelayStat(
|
|||||||
messages.put(debugMessage, debugMessage)
|
messages.put(debugMessage, debugMessage)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addBytesReceived(bytesUsedInMemory: Int) {
|
fun addBytesReceived(bytesUsedInMemory: Long) {
|
||||||
receivedBytes += bytesUsedInMemory
|
receivedBytes += bytesUsedInMemory
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addBytesSent(bytesUsedInMemory: Int) {
|
fun addBytesSent(bytesUsedInMemory: Long) {
|
||||||
sentBytes += bytesUsedInMemory
|
sentBytes += bytesUsedInMemory
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ package com.vitorpamplona.quartz.encoders
|
|||||||
|
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import androidx.compose.runtime.Immutable
|
import androidx.compose.runtime.Immutable
|
||||||
|
import com.vitorpamplona.quartz.utils.bytesUsedInMemory
|
||||||
|
import com.vitorpamplona.quartz.utils.pointerSizeInBytes
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
data class ATag(
|
data class ATag(
|
||||||
@@ -30,6 +32,13 @@ data class ATag(
|
|||||||
val dTag: String,
|
val dTag: String,
|
||||||
val relay: String?,
|
val relay: String?,
|
||||||
) {
|
) {
|
||||||
|
fun countMemory(): Long =
|
||||||
|
5 * pointerSizeInBytes + // 7 fields, 4 bytes each reference (32bit)
|
||||||
|
8L + // kind
|
||||||
|
pubKeyHex.bytesUsedInMemory() +
|
||||||
|
dTag.bytesUsedInMemory() +
|
||||||
|
(relay?.bytesUsedInMemory() ?: 0)
|
||||||
|
|
||||||
fun toTag() = assembleATag(kind, pubKeyHex, dTag)
|
fun toTag() = assembleATag(kind, pubKeyHex, dTag)
|
||||||
|
|
||||||
fun toNAddr(): String =
|
fun toNAddr(): String =
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ import com.fasterxml.jackson.annotation.JsonProperty
|
|||||||
import com.vitorpamplona.quartz.encoders.HexKey
|
import com.vitorpamplona.quartz.encoders.HexKey
|
||||||
import com.vitorpamplona.quartz.signers.NostrSigner
|
import com.vitorpamplona.quartz.signers.NostrSigner
|
||||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||||
|
import com.vitorpamplona.quartz.utils.bytesUsedInMemory
|
||||||
|
import com.vitorpamplona.quartz.utils.pointerSizeInBytes
|
||||||
import java.io.ByteArrayInputStream
|
import java.io.ByteArrayInputStream
|
||||||
|
|
||||||
@Stable
|
@Stable
|
||||||
@@ -58,6 +60,28 @@ class AppMetadata {
|
|||||||
@Transient
|
@Transient
|
||||||
var tags: ImmutableListOfLists<String>? = null
|
var tags: ImmutableListOfLists<String>? = null
|
||||||
|
|
||||||
|
fun countMemory(): Long =
|
||||||
|
20 * pointerSizeInBytes + // 20 fields, 4 bytes for each reference
|
||||||
|
(name?.bytesUsedInMemory() ?: 0L) +
|
||||||
|
(username?.bytesUsedInMemory() ?: 0L) +
|
||||||
|
(displayName?.bytesUsedInMemory() ?: 0L) +
|
||||||
|
(picture?.bytesUsedInMemory() ?: 0L) +
|
||||||
|
(banner?.bytesUsedInMemory() ?: 0L) +
|
||||||
|
(image?.bytesUsedInMemory() ?: 0L) +
|
||||||
|
(website?.bytesUsedInMemory() ?: 0L) +
|
||||||
|
(about?.bytesUsedInMemory() ?: 0L) +
|
||||||
|
(subscription?.bytesUsedInMemory() ?: 0L) +
|
||||||
|
(cashuAccepted?.bytesUsedInMemory() ?: 0L) +
|
||||||
|
(encryptionSupported?.bytesUsedInMemory() ?: 0L) +
|
||||||
|
(personalized?.bytesUsedInMemory() ?: 0L) + // A Boolean has 8 bytes of header, plus 1 byte of payload, for a total of 9 bytes of information. The JVM then rounds it up to the next multiple of 8. so the one instance of java.lang.Boolean takes up 16 bytes of memory.
|
||||||
|
(amount?.bytesUsedInMemory() ?: 0L) +
|
||||||
|
(nip05?.bytesUsedInMemory() ?: 0L) +
|
||||||
|
(domain?.bytesUsedInMemory() ?: 0L) +
|
||||||
|
(lud06?.bytesUsedInMemory() ?: 0L) +
|
||||||
|
(lud16?.bytesUsedInMemory() ?: 0L) +
|
||||||
|
(twitter?.bytesUsedInMemory() ?: 0L) +
|
||||||
|
(tags?.lists?.sumOf { it.sumOf { it.bytesUsedInMemory() } } ?: 0L)
|
||||||
|
|
||||||
fun anyName(): String? = displayName ?: name ?: username
|
fun anyName(): String? = displayName ?: name ?: username
|
||||||
|
|
||||||
fun anyNameStartsWith(prefix: String): Boolean =
|
fun anyNameStartsWith(prefix: String): Boolean =
|
||||||
@@ -108,6 +132,8 @@ class AppDefinitionEvent(
|
|||||||
content: String,
|
content: String,
|
||||||
sig: HexKey,
|
sig: HexKey,
|
||||||
) : BaseAddressableEvent(id, pubKey, createdAt, KIND, tags, content, sig) {
|
) : BaseAddressableEvent(id, pubKey, createdAt, KIND, tags, content, sig) {
|
||||||
|
override fun countMemory(): Long = super.countMemory() + (cachedMetadata?.countMemory() ?: 8L)
|
||||||
|
|
||||||
@Transient private var cachedMetadata: AppMetadata? = null
|
@Transient private var cachedMetadata: AppMetadata? = null
|
||||||
|
|
||||||
fun appMetaData() =
|
fun appMetaData() =
|
||||||
|
|||||||
@@ -24,6 +24,8 @@ import androidx.compose.runtime.Immutable
|
|||||||
import com.vitorpamplona.quartz.encoders.HexKey
|
import com.vitorpamplona.quartz.encoders.HexKey
|
||||||
import com.vitorpamplona.quartz.signers.NostrSigner
|
import com.vitorpamplona.quartz.signers.NostrSigner
|
||||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||||
|
import com.vitorpamplona.quartz.utils.bytesUsedInMemory
|
||||||
|
import com.vitorpamplona.quartz.utils.pointerSizeInBytes
|
||||||
import kotlinx.collections.immutable.ImmutableSet
|
import kotlinx.collections.immutable.ImmutableSet
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
@@ -37,6 +39,10 @@ class ChannelListEvent(
|
|||||||
) : GeneralListEvent(id, pubKey, createdAt, KIND, tags, content, sig) {
|
) : GeneralListEvent(id, pubKey, createdAt, KIND, tags, content, sig) {
|
||||||
@Transient var publicAndPrivateEventCache: ImmutableSet<HexKey>? = null
|
@Transient var publicAndPrivateEventCache: ImmutableSet<HexKey>? = null
|
||||||
|
|
||||||
|
override fun countMemory(): Long =
|
||||||
|
super.countMemory() +
|
||||||
|
32 + (publicAndPrivateEventCache?.sumOf { pointerSizeInBytes + it.bytesUsedInMemory() } ?: 0L) // rough calculation
|
||||||
|
|
||||||
override fun dTag() = FIXED_D_TAG
|
override fun dTag() = FIXED_D_TAG
|
||||||
|
|
||||||
fun publicAndPrivateEvents(
|
fun publicAndPrivateEvents(
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import com.vitorpamplona.quartz.encoders.ATag
|
|||||||
import com.vitorpamplona.quartz.encoders.HexKey
|
import com.vitorpamplona.quartz.encoders.HexKey
|
||||||
import com.vitorpamplona.quartz.signers.NostrSigner
|
import com.vitorpamplona.quartz.signers.NostrSigner
|
||||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||||
|
import com.vitorpamplona.quartz.utils.pointerSizeInBytes
|
||||||
import kotlinx.collections.immutable.ImmutableSet
|
import kotlinx.collections.immutable.ImmutableSet
|
||||||
import kotlinx.collections.immutable.toImmutableSet
|
import kotlinx.collections.immutable.toImmutableSet
|
||||||
|
|
||||||
@@ -39,6 +40,10 @@ class CommunityListEvent(
|
|||||||
) : GeneralListEvent(id, pubKey, createdAt, KIND, tags, content, sig) {
|
) : GeneralListEvent(id, pubKey, createdAt, KIND, tags, content, sig) {
|
||||||
@Transient var publicAndPrivateEventCache: ImmutableSet<ATag>? = null
|
@Transient var publicAndPrivateEventCache: ImmutableSet<ATag>? = null
|
||||||
|
|
||||||
|
override fun countMemory(): Long =
|
||||||
|
super.countMemory() +
|
||||||
|
32 + (publicAndPrivateEventCache?.sumOf { pointerSizeInBytes + it.countMemory() } ?: 0L) // rough calculation
|
||||||
|
|
||||||
override fun dTag() = FIXED_D_TAG
|
override fun dTag() = FIXED_D_TAG
|
||||||
|
|
||||||
fun publicAndPrivateEvents(
|
fun publicAndPrivateEvents(
|
||||||
|
|||||||
@@ -46,40 +46,35 @@ class ContactListEvent(
|
|||||||
content: String,
|
content: String,
|
||||||
sig: HexKey,
|
sig: HexKey,
|
||||||
) : Event(id, pubKey, createdAt, KIND, tags, content, sig) {
|
) : Event(id, pubKey, createdAt, KIND, tags, content, sig) {
|
||||||
// This function is only used by the user logged in
|
/**
|
||||||
// But it is used all the time.
|
* Returns a list of p-tags that are verified as hex keys.
|
||||||
|
*/
|
||||||
@delegate:Transient
|
fun verifiedFollowKeySet(): Set<HexKey> =
|
||||||
val verifiedFollowKeySet: Set<HexKey> by lazy {
|
tags.mapNotNullTo(mutableSetOf()) {
|
||||||
tags.mapNotNullTo(HashSet()) {
|
if (it.size > 1 && it[0] == "p") {
|
||||||
try {
|
try {
|
||||||
if (it.size > 1 && it[0] == "p") {
|
|
||||||
decodePublicKey(it[1]).toHexKey()
|
decodePublicKey(it[1]).toHexKey()
|
||||||
} else {
|
} catch (e: Exception) {
|
||||||
|
Log.w("ContactListEvent", "Can't parse p-tag $it in the contact list of $pubKey with id $id", e)
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} else {
|
||||||
Log.w("ContactListEvent", "Can't parse tags as a follows: ${it[1]}", e)
|
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@delegate:Transient
|
/**
|
||||||
val verifiedFollowTagSet: Set<String> by lazy {
|
* Returns a list of a-tags that are verified as correct.
|
||||||
unverifiedFollowTagSet().map { it.lowercase() }.toSet()
|
*/
|
||||||
}
|
fun verifiedFollowAddressSet(): Set<HexKey> =
|
||||||
|
tags
|
||||||
@delegate:Transient
|
.mapNotNullTo(mutableSetOf()) {
|
||||||
val verifiedFollowGeohashSet: Set<String> by lazy {
|
if (it.size > 1 && it[0] == "a") {
|
||||||
unverifiedFollowGeohashSet().map { it.lowercase() }.toSet()
|
ATag.parse(it[1], null)?.toTag()
|
||||||
}
|
} else {
|
||||||
|
null
|
||||||
@delegate:Transient
|
}
|
||||||
val verifiedFollowCommunitySet: Set<String> by lazy { unverifiedFollowAddressSet().toSet() }
|
}
|
||||||
|
|
||||||
@delegate:Transient
|
|
||||||
val verifiedFollowKeySetAndMe: Set<HexKey> by lazy { verifiedFollowKeySet + pubKey }
|
|
||||||
|
|
||||||
fun unverifiedFollowKeySet() = tags.filter { it.size > 1 && it[0] == "p" }.mapNotNull { it.getOrNull(1) }
|
fun unverifiedFollowKeySet() = tags.filter { it.size > 1 && it[0] == "p" }.mapNotNull { it.getOrNull(1) }
|
||||||
|
|
||||||
@@ -105,7 +100,7 @@ class ContactListEvent(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun followsTags() = tags.filter { it.size > 1 && it[0] == "t" }.mapNotNull { it.getOrNull(1) }
|
fun followsTags() = hashtags()
|
||||||
|
|
||||||
fun relays(): Map<String, ReadWrite>? =
|
fun relays(): Map<String, ReadWrite>? =
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import com.vitorpamplona.quartz.encoders.ATag
|
|||||||
import com.vitorpamplona.quartz.encoders.HexKey
|
import com.vitorpamplona.quartz.encoders.HexKey
|
||||||
import com.vitorpamplona.quartz.signers.NostrSigner
|
import com.vitorpamplona.quartz.signers.NostrSigner
|
||||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||||
|
import com.vitorpamplona.quartz.utils.pointerSizeInBytes
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
class DraftEvent(
|
class DraftEvent(
|
||||||
@@ -37,6 +38,10 @@ class DraftEvent(
|
|||||||
) : BaseAddressableEvent(id, pubKey, createdAt, KIND, tags, content, sig) {
|
) : BaseAddressableEvent(id, pubKey, createdAt, KIND, tags, content, sig) {
|
||||||
@Transient private var cachedInnerEvent: Map<HexKey, Event?> = mapOf()
|
@Transient private var cachedInnerEvent: Map<HexKey, Event?> = mapOf()
|
||||||
|
|
||||||
|
override fun countMemory(): Long =
|
||||||
|
super.countMemory() +
|
||||||
|
32 + (cachedInnerEvent.values.sumOf { pointerSizeInBytes + (it?.countMemory() ?: 0) })
|
||||||
|
|
||||||
override fun isContentEncoded() = true
|
override fun isContentEncoded() = true
|
||||||
|
|
||||||
fun isDeleted() = content == ""
|
fun isDeleted() = content == ""
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ import com.vitorpamplona.quartz.encoders.toHexKey
|
|||||||
import com.vitorpamplona.quartz.signers.NostrSigner
|
import com.vitorpamplona.quartz.signers.NostrSigner
|
||||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||||
import com.vitorpamplona.quartz.utils.bytesUsedInMemory
|
import com.vitorpamplona.quartz.utils.bytesUsedInMemory
|
||||||
|
import com.vitorpamplona.quartz.utils.pointerSizeInBytes
|
||||||
import java.math.BigDecimal
|
import java.math.BigDecimal
|
||||||
import java.security.MessageDigest
|
import java.security.MessageDigest
|
||||||
|
|
||||||
@@ -60,10 +61,11 @@ open class Event(
|
|||||||
override fun isContentEncoded() = false
|
override fun isContentEncoded() = false
|
||||||
|
|
||||||
override fun countMemory(): Long =
|
override fun countMemory(): Long =
|
||||||
12L +
|
7 * pointerSizeInBytes + // 7 fields, 4 bytes each reference (32bit)
|
||||||
|
12L + // createdAt + kind
|
||||||
id.bytesUsedInMemory() +
|
id.bytesUsedInMemory() +
|
||||||
pubKey.bytesUsedInMemory() +
|
pubKey.bytesUsedInMemory() +
|
||||||
tags.sumOf { it.sumOf { it.bytesUsedInMemory() } } +
|
tags.sumOf { pointerSizeInBytes + it.sumOf { pointerSizeInBytes + it.bytesUsedInMemory() } } +
|
||||||
content.bytesUsedInMemory() +
|
content.bytesUsedInMemory() +
|
||||||
sig.bytesUsedInMemory()
|
sig.bytesUsedInMemory()
|
||||||
|
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ class GalleryListEvent(
|
|||||||
createdAt: Long = TimeUtils.now(),
|
createdAt: Long = TimeUtils.now(),
|
||||||
onReady: (GalleryListEvent) -> Unit,
|
onReady: (GalleryListEvent) -> Unit,
|
||||||
) {
|
) {
|
||||||
var tags = arrayOf(tagName, url, eventid)
|
val tags = arrayOf(tagName, url, eventid)
|
||||||
if (relay != null) {
|
if (relay != null) {
|
||||||
tags + relay
|
tags + relay
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ import com.fasterxml.jackson.module.kotlin.readValue
|
|||||||
import com.vitorpamplona.quartz.encoders.ATag
|
import com.vitorpamplona.quartz.encoders.ATag
|
||||||
import com.vitorpamplona.quartz.encoders.HexKey
|
import com.vitorpamplona.quartz.encoders.HexKey
|
||||||
import com.vitorpamplona.quartz.signers.NostrSigner
|
import com.vitorpamplona.quartz.signers.NostrSigner
|
||||||
|
import com.vitorpamplona.quartz.utils.bytesUsedInMemory
|
||||||
|
import com.vitorpamplona.quartz.utils.pointerSizeInBytes
|
||||||
import kotlinx.collections.immutable.ImmutableSet
|
import kotlinx.collections.immutable.ImmutableSet
|
||||||
import kotlinx.collections.immutable.toImmutableSet
|
import kotlinx.collections.immutable.toImmutableSet
|
||||||
import java.util.HashSet
|
import java.util.HashSet
|
||||||
@@ -42,6 +44,10 @@ abstract class GeneralListEvent(
|
|||||||
) : BaseAddressableEvent(id, pubKey, createdAt, kind, tags, content, sig) {
|
) : BaseAddressableEvent(id, pubKey, createdAt, kind, tags, content, sig) {
|
||||||
@Transient private var privateTagsCache: Array<Array<String>>? = null
|
@Transient private var privateTagsCache: Array<Array<String>>? = null
|
||||||
|
|
||||||
|
override fun countMemory(): Long =
|
||||||
|
super.countMemory() +
|
||||||
|
pointerSizeInBytes + (privateTagsCache?.sumOf { pointerSizeInBytes + it.sumOf { pointerSizeInBytes + it.bytesUsedInMemory() } } ?: 0)
|
||||||
|
|
||||||
override fun isContentEncoded() = true
|
override fun isContentEncoded() = true
|
||||||
|
|
||||||
fun category() = dTag()
|
fun category() = dTag()
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import com.vitorpamplona.quartz.encoders.HexKey
|
|||||||
import com.vitorpamplona.quartz.signers.NostrSigner
|
import com.vitorpamplona.quartz.signers.NostrSigner
|
||||||
import com.vitorpamplona.quartz.signers.NostrSignerInternal
|
import com.vitorpamplona.quartz.signers.NostrSignerInternal
|
||||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||||
|
import com.vitorpamplona.quartz.utils.pointerSizeInBytes
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
class GiftWrapEvent(
|
class GiftWrapEvent(
|
||||||
@@ -38,6 +39,10 @@ class GiftWrapEvent(
|
|||||||
) : Event(id, pubKey, createdAt, KIND, tags, content, sig) {
|
) : Event(id, pubKey, createdAt, KIND, tags, content, sig) {
|
||||||
@Transient private var cachedInnerEvent: Map<HexKey, Event?> = mapOf()
|
@Transient private var cachedInnerEvent: Map<HexKey, Event?> = mapOf()
|
||||||
|
|
||||||
|
override fun countMemory(): Long =
|
||||||
|
super.countMemory() +
|
||||||
|
32 + (cachedInnerEvent.values.sumOf { pointerSizeInBytes + (it?.countMemory() ?: 0) }) // rough calculation
|
||||||
|
|
||||||
fun copyNoContent(): GiftWrapEvent {
|
fun copyNoContent(): GiftWrapEvent {
|
||||||
val copy =
|
val copy =
|
||||||
GiftWrapEvent(
|
GiftWrapEvent(
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import android.util.Log
|
|||||||
import androidx.compose.runtime.Immutable
|
import androidx.compose.runtime.Immutable
|
||||||
import com.vitorpamplona.quartz.encoders.HexKey
|
import com.vitorpamplona.quartz.encoders.HexKey
|
||||||
import com.vitorpamplona.quartz.encoders.LnInvoiceUtil
|
import com.vitorpamplona.quartz.encoders.LnInvoiceUtil
|
||||||
|
import com.vitorpamplona.quartz.utils.pointerSizeInBytes
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
class LnZapEvent(
|
class LnZapEvent(
|
||||||
@@ -38,6 +39,10 @@ class LnZapEvent(
|
|||||||
// This event is also kept in LocalCache (same object)
|
// This event is also kept in LocalCache (same object)
|
||||||
@Transient val zapRequest: LnZapRequestEvent?
|
@Transient val zapRequest: LnZapRequestEvent?
|
||||||
|
|
||||||
|
override fun countMemory(): Long =
|
||||||
|
super.countMemory() +
|
||||||
|
pointerSizeInBytes + (zapRequest?.countMemory() ?: 0) // rough calculation
|
||||||
|
|
||||||
override fun containedPost(): LnZapRequestEvent? =
|
override fun containedPost(): LnZapRequestEvent? =
|
||||||
try {
|
try {
|
||||||
description()?.ifBlank { null }?.let { fromJson(it) } as? LnZapRequestEvent
|
description()?.ifBlank { null }?.let { fromJson(it) } as? LnZapRequestEvent
|
||||||
|
|||||||
@@ -29,6 +29,8 @@ import com.fasterxml.jackson.databind.deser.std.StdDeserializer
|
|||||||
import com.vitorpamplona.quartz.encoders.HexKey
|
import com.vitorpamplona.quartz.encoders.HexKey
|
||||||
import com.vitorpamplona.quartz.signers.NostrSigner
|
import com.vitorpamplona.quartz.signers.NostrSigner
|
||||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||||
|
import com.vitorpamplona.quartz.utils.bytesUsedInMemory
|
||||||
|
import com.vitorpamplona.quartz.utils.pointerSizeInBytes
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
class LnZapPaymentRequestEvent(
|
class LnZapPaymentRequestEvent(
|
||||||
@@ -42,6 +44,10 @@ class LnZapPaymentRequestEvent(
|
|||||||
// Once one of an app user decrypts the payment, all users else can see it.
|
// Once one of an app user decrypts the payment, all users else can see it.
|
||||||
@Transient private var lnInvoice: String? = null
|
@Transient private var lnInvoice: String? = null
|
||||||
|
|
||||||
|
override fun countMemory(): Long =
|
||||||
|
super.countMemory() +
|
||||||
|
pointerSizeInBytes + (lnInvoice?.bytesUsedInMemory() ?: 0) // rough calculation
|
||||||
|
|
||||||
fun walletServicePubKey() = tags.firstOrNull { it.size > 1 && it[0] == "p" }?.get(1)
|
fun walletServicePubKey() = tags.firstOrNull { it.size > 1 && it[0] == "p" }?.get(1)
|
||||||
|
|
||||||
fun talkingWith(oneSideHex: String): HexKey = if (pubKey == oneSideHex) walletServicePubKey() ?: pubKey else pubKey
|
fun talkingWith(oneSideHex: String): HexKey = if (pubKey == oneSideHex) walletServicePubKey() ?: pubKey else pubKey
|
||||||
|
|||||||
@@ -29,6 +29,8 @@ import com.fasterxml.jackson.databind.JsonNode
|
|||||||
import com.fasterxml.jackson.databind.deser.std.StdDeserializer
|
import com.fasterxml.jackson.databind.deser.std.StdDeserializer
|
||||||
import com.vitorpamplona.quartz.encoders.HexKey
|
import com.vitorpamplona.quartz.encoders.HexKey
|
||||||
import com.vitorpamplona.quartz.signers.NostrSigner
|
import com.vitorpamplona.quartz.signers.NostrSigner
|
||||||
|
import com.vitorpamplona.quartz.utils.bytesUsedInMemory
|
||||||
|
import com.vitorpamplona.quartz.utils.pointerSizeInBytes
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
class LnZapPaymentResponseEvent(
|
class LnZapPaymentResponseEvent(
|
||||||
@@ -42,6 +44,8 @@ class LnZapPaymentResponseEvent(
|
|||||||
// Once one of an app user decrypts the payment, all users else can see it.
|
// Once one of an app user decrypts the payment, all users else can see it.
|
||||||
@Transient private var response: Response? = null
|
@Transient private var response: Response? = null
|
||||||
|
|
||||||
|
override fun countMemory(): Long = super.countMemory() + pointerSizeInBytes + (response?.countMemory() ?: 0)
|
||||||
|
|
||||||
fun requestAuthor() = tags.firstOrNull { it.size > 1 && it[0] == "p" }?.get(1)
|
fun requestAuthor() = tags.firstOrNull { it.size > 1 && it[0] == "p" }?.get(1)
|
||||||
|
|
||||||
fun requestId() = tags.firstOrNull { it.size > 1 && it[0] == "e" }?.get(1)
|
fun requestId() = tags.firstOrNull { it.size > 1 && it[0] == "e" }?.get(1)
|
||||||
@@ -91,7 +95,9 @@ class LnZapPaymentResponseEvent(
|
|||||||
// RESPONSE OBJECTS
|
// RESPONSE OBJECTS
|
||||||
abstract class Response(
|
abstract class Response(
|
||||||
@JsonProperty("result_type") val resultType: String,
|
@JsonProperty("result_type") val resultType: String,
|
||||||
)
|
) {
|
||||||
|
abstract fun countMemory(): Long
|
||||||
|
}
|
||||||
|
|
||||||
// PayInvoice Call
|
// PayInvoice Call
|
||||||
|
|
||||||
@@ -100,7 +106,11 @@ class PayInvoiceSuccessResponse(
|
|||||||
) : Response("pay_invoice") {
|
) : Response("pay_invoice") {
|
||||||
class PayInvoiceResultParams(
|
class PayInvoiceResultParams(
|
||||||
val preimage: String,
|
val preimage: String,
|
||||||
)
|
) {
|
||||||
|
fun countMemory(): Long = pointerSizeInBytes + preimage.bytesUsedInMemory()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun countMemory(): Long = pointerSizeInBytes + (result?.countMemory() ?: 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
class PayInvoiceErrorResponse(
|
class PayInvoiceErrorResponse(
|
||||||
@@ -109,7 +119,11 @@ class PayInvoiceErrorResponse(
|
|||||||
class PayInvoiceErrorParams(
|
class PayInvoiceErrorParams(
|
||||||
val code: ErrorType?,
|
val code: ErrorType?,
|
||||||
val message: String?,
|
val message: String?,
|
||||||
)
|
) {
|
||||||
|
fun countMemory(): Long = pointerSizeInBytes + pointerSizeInBytes + (message?.bytesUsedInMemory() ?: 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun countMemory(): Long = pointerSizeInBytes + (error?.countMemory() ?: 0)
|
||||||
|
|
||||||
enum class ErrorType {
|
enum class ErrorType {
|
||||||
@JsonProperty(value = "RATE_LIMITED")
|
@JsonProperty(value = "RATE_LIMITED")
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import com.vitorpamplona.quartz.encoders.hexToByteArray
|
|||||||
import com.vitorpamplona.quartz.signers.NostrSigner
|
import com.vitorpamplona.quartz.signers.NostrSigner
|
||||||
import com.vitorpamplona.quartz.signers.NostrSignerInternal
|
import com.vitorpamplona.quartz.signers.NostrSignerInternal
|
||||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||||
|
import com.vitorpamplona.quartz.utils.pointerSizeInBytes
|
||||||
import java.nio.charset.Charset
|
import java.nio.charset.Charset
|
||||||
import java.security.SecureRandom
|
import java.security.SecureRandom
|
||||||
import javax.crypto.BadPaddingException
|
import javax.crypto.BadPaddingException
|
||||||
@@ -47,6 +48,8 @@ class LnZapRequestEvent(
|
|||||||
) : Event(id, pubKey, createdAt, KIND, tags, content, sig) {
|
) : Event(id, pubKey, createdAt, KIND, tags, content, sig) {
|
||||||
@Transient private var privateZapEvent: LnZapPrivateEvent? = null
|
@Transient private var privateZapEvent: LnZapPrivateEvent? = null
|
||||||
|
|
||||||
|
override fun countMemory(): Long = super.countMemory() + pointerSizeInBytes + (privateZapEvent?.countMemory() ?: 0)
|
||||||
|
|
||||||
fun zappedPost() = tags.filter { it.size > 1 && it[0] == "e" }.map { it[1] }
|
fun zappedPost() = tags.filter { it.size > 1 && it[0] == "e" }.map { it[1] }
|
||||||
|
|
||||||
fun zappedAuthor() = tags.filter { it.size > 1 && it[0] == "p" }.map { it[1] }
|
fun zappedAuthor() = tags.filter { it.size > 1 && it[0] == "p" }.map { it[1] }
|
||||||
|
|||||||
@@ -24,6 +24,8 @@ import androidx.compose.runtime.Immutable
|
|||||||
import com.vitorpamplona.quartz.encoders.HexKey
|
import com.vitorpamplona.quartz.encoders.HexKey
|
||||||
import com.vitorpamplona.quartz.signers.NostrSigner
|
import com.vitorpamplona.quartz.signers.NostrSigner
|
||||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||||
|
import com.vitorpamplona.quartz.utils.bytesUsedInMemory
|
||||||
|
import com.vitorpamplona.quartz.utils.pointerSizeInBytes
|
||||||
import kotlinx.collections.immutable.ImmutableSet
|
import kotlinx.collections.immutable.ImmutableSet
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
@@ -39,6 +41,11 @@ class MuteListEvent(
|
|||||||
|
|
||||||
@Transient var publicAndPrivateWordCache: ImmutableSet<String>? = null
|
@Transient var publicAndPrivateWordCache: ImmutableSet<String>? = null
|
||||||
|
|
||||||
|
override fun countMemory(): Long =
|
||||||
|
super.countMemory() +
|
||||||
|
pointerSizeInBytes + (publicAndPrivateUserCache?.sumOf { pointerSizeInBytes + it.bytesUsedInMemory() } ?: 0) +
|
||||||
|
pointerSizeInBytes + (publicAndPrivateWordCache?.sumOf { pointerSizeInBytes + it.bytesUsedInMemory() } ?: 0)
|
||||||
|
|
||||||
override fun dTag() = FIXED_D_TAG
|
override fun dTag() = FIXED_D_TAG
|
||||||
|
|
||||||
fun publicAndPrivateUsersAndWords(
|
fun publicAndPrivateUsersAndWords(
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ import com.fasterxml.jackson.module.kotlin.readValue
|
|||||||
import com.vitorpamplona.quartz.encoders.HexKey
|
import com.vitorpamplona.quartz.encoders.HexKey
|
||||||
import com.vitorpamplona.quartz.signers.NostrSigner
|
import com.vitorpamplona.quartz.signers.NostrSigner
|
||||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||||
|
import com.vitorpamplona.quartz.utils.bytesUsedInMemory
|
||||||
|
import com.vitorpamplona.quartz.utils.pointerSizeInBytes
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
class NIP90ContentDiscoveryResponseEvent(
|
class NIP90ContentDiscoveryResponseEvent(
|
||||||
@@ -38,6 +40,10 @@ class NIP90ContentDiscoveryResponseEvent(
|
|||||||
) : Event(id, pubKey, createdAt, KIND, tags, content, sig) {
|
) : Event(id, pubKey, createdAt, KIND, tags, content, sig) {
|
||||||
@Transient var events: List<HexKey>? = null
|
@Transient var events: List<HexKey>? = null
|
||||||
|
|
||||||
|
override fun countMemory(): Long =
|
||||||
|
super.countMemory() +
|
||||||
|
pointerSizeInBytes + (events?.sumOf { it.bytesUsedInMemory() } ?: 0)
|
||||||
|
|
||||||
fun innerTags(): List<HexKey> {
|
fun innerTags(): List<HexKey> {
|
||||||
if (content.isEmpty()) {
|
if (content.isEmpty()) {
|
||||||
return listOf()
|
return listOf()
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ import com.vitorpamplona.quartz.ots.VerifyResult
|
|||||||
import com.vitorpamplona.quartz.ots.op.OpSHA256
|
import com.vitorpamplona.quartz.ots.op.OpSHA256
|
||||||
import com.vitorpamplona.quartz.signers.NostrSigner
|
import com.vitorpamplona.quartz.signers.NostrSigner
|
||||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||||
|
import com.vitorpamplona.quartz.utils.pointerSizeInBytes
|
||||||
import kotlinx.coroutines.CancellationException
|
import kotlinx.coroutines.CancellationException
|
||||||
import java.util.Base64
|
import java.util.Base64
|
||||||
|
|
||||||
@@ -48,6 +49,10 @@ class OtsEvent(
|
|||||||
@Transient
|
@Transient
|
||||||
var verifiedTime: Long? = null
|
var verifiedTime: Long? = null
|
||||||
|
|
||||||
|
override fun countMemory(): Long =
|
||||||
|
super.countMemory() +
|
||||||
|
pointerSizeInBytes + Long.SIZE_BYTES // verifiedTime
|
||||||
|
|
||||||
override fun isContentEncoded() = true
|
override fun isContentEncoded() = true
|
||||||
|
|
||||||
fun digestEvent() = tags.firstOrNull { it.size > 1 && it[0] == "e" }?.get(1)
|
fun digestEvent() = tags.firstOrNull { it.size > 1 && it[0] == "e" }?.get(1)
|
||||||
|
|||||||
@@ -24,6 +24,8 @@ import androidx.compose.runtime.Immutable
|
|||||||
import com.vitorpamplona.quartz.encoders.HexKey
|
import com.vitorpamplona.quartz.encoders.HexKey
|
||||||
import com.vitorpamplona.quartz.signers.NostrSigner
|
import com.vitorpamplona.quartz.signers.NostrSigner
|
||||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||||
|
import com.vitorpamplona.quartz.utils.bytesUsedInMemory
|
||||||
|
import com.vitorpamplona.quartz.utils.pointerSizeInBytes
|
||||||
import kotlinx.collections.immutable.ImmutableSet
|
import kotlinx.collections.immutable.ImmutableSet
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
@@ -39,6 +41,11 @@ class PeopleListEvent(
|
|||||||
|
|
||||||
@Transient var publicAndPrivateWordCache: ImmutableSet<String>? = null
|
@Transient var publicAndPrivateWordCache: ImmutableSet<String>? = null
|
||||||
|
|
||||||
|
override fun countMemory(): Long =
|
||||||
|
super.countMemory() +
|
||||||
|
pointerSizeInBytes + (publicAndPrivateUserCache?.sumOf { pointerSizeInBytes + it.bytesUsedInMemory() } ?: 0) +
|
||||||
|
pointerSizeInBytes + (publicAndPrivateWordCache?.sumOf { pointerSizeInBytes + it.bytesUsedInMemory() } ?: 0)
|
||||||
|
|
||||||
fun publicAndPrivateWords(
|
fun publicAndPrivateWords(
|
||||||
signer: NostrSigner,
|
signer: NostrSigner,
|
||||||
onReady: (ImmutableSet<String>) -> Unit,
|
onReady: (ImmutableSet<String>) -> Unit,
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ import com.vitorpamplona.quartz.encoders.HexValidator
|
|||||||
import com.vitorpamplona.quartz.encoders.Nip54InlineMetadata
|
import com.vitorpamplona.quartz.encoders.Nip54InlineMetadata
|
||||||
import com.vitorpamplona.quartz.signers.NostrSigner
|
import com.vitorpamplona.quartz.signers.NostrSigner
|
||||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||||
|
import com.vitorpamplona.quartz.utils.bytesUsedInMemory
|
||||||
|
import com.vitorpamplona.quartz.utils.pointerSizeInBytes
|
||||||
import kotlinx.collections.immutable.persistentSetOf
|
import kotlinx.collections.immutable.persistentSetOf
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
@@ -41,6 +43,10 @@ class PrivateDmEvent(
|
|||||||
ChatroomKeyable {
|
ChatroomKeyable {
|
||||||
@Transient private var decryptedContent: Map<HexKey, String> = mapOf()
|
@Transient private var decryptedContent: Map<HexKey, String> = mapOf()
|
||||||
|
|
||||||
|
override fun countMemory(): Long =
|
||||||
|
super.countMemory() +
|
||||||
|
pointerSizeInBytes + (decryptedContent.values.sumOf { pointerSizeInBytes + it.bytesUsedInMemory() })
|
||||||
|
|
||||||
override fun isContentEncoded() = true
|
override fun isContentEncoded() = true
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ import com.vitorpamplona.quartz.encoders.ATag
|
|||||||
import com.vitorpamplona.quartz.encoders.HexKey
|
import com.vitorpamplona.quartz.encoders.HexKey
|
||||||
import com.vitorpamplona.quartz.signers.NostrSigner
|
import com.vitorpamplona.quartz.signers.NostrSigner
|
||||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||||
|
import com.vitorpamplona.quartz.utils.bytesUsedInMemory
|
||||||
|
import com.vitorpamplona.quartz.utils.pointerSizeInBytes
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
class PrivateOutboxRelayListEvent(
|
class PrivateOutboxRelayListEvent(
|
||||||
@@ -39,6 +41,10 @@ class PrivateOutboxRelayListEvent(
|
|||||||
) : BaseAddressableEvent(id, pubKey, createdAt, KIND, tags, content, sig) {
|
) : BaseAddressableEvent(id, pubKey, createdAt, KIND, tags, content, sig) {
|
||||||
@Transient private var privateTagsCache: Array<Array<String>>? = null
|
@Transient private var privateTagsCache: Array<Array<String>>? = null
|
||||||
|
|
||||||
|
override fun countMemory(): Long =
|
||||||
|
super.countMemory() +
|
||||||
|
pointerSizeInBytes + (privateTagsCache?.sumOf { pointerSizeInBytes + it.sumOf { pointerSizeInBytes + it.bytesUsedInMemory() } } ?: 0)
|
||||||
|
|
||||||
override fun dTag() = FIXED_D_TAG
|
override fun dTag() = FIXED_D_TAG
|
||||||
|
|
||||||
fun relays(): List<String>? =
|
fun relays(): List<String>? =
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import com.vitorpamplona.quartz.encoders.HexKey
|
|||||||
import com.vitorpamplona.quartz.encoders.toHexKey
|
import com.vitorpamplona.quartz.encoders.toHexKey
|
||||||
import com.vitorpamplona.quartz.signers.NostrSigner
|
import com.vitorpamplona.quartz.signers.NostrSigner
|
||||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||||
|
import com.vitorpamplona.quartz.utils.pointerSizeInBytes
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
class SealedGossipEvent(
|
class SealedGossipEvent(
|
||||||
@@ -39,6 +40,10 @@ class SealedGossipEvent(
|
|||||||
) : WrappedEvent(id, pubKey, createdAt, KIND, tags, content, sig) {
|
) : WrappedEvent(id, pubKey, createdAt, KIND, tags, content, sig) {
|
||||||
@Transient private var cachedInnerEvent: Map<HexKey, Event?> = mapOf()
|
@Transient private var cachedInnerEvent: Map<HexKey, Event?> = mapOf()
|
||||||
|
|
||||||
|
override fun countMemory(): Long =
|
||||||
|
super.countMemory() +
|
||||||
|
pointerSizeInBytes + cachedInnerEvent.values.sumOf { pointerSizeInBytes + (it?.countMemory() ?: 0) }
|
||||||
|
|
||||||
fun copyNoContent(): SealedGossipEvent {
|
fun copyNoContent(): SealedGossipEvent {
|
||||||
val copy =
|
val copy =
|
||||||
SealedGossipEvent(
|
SealedGossipEvent(
|
||||||
|
|||||||
@@ -22,7 +22,11 @@ package com.vitorpamplona.quartz.utils
|
|||||||
|
|
||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
|
|
||||||
fun String.bytesUsedInMemory(): Int = (8 * ((((this.length) * 2) + 45) / 8))
|
val pointerSizeInBytes = 4
|
||||||
|
|
||||||
|
fun String.bytesUsedInMemory(): Long = (8 * (((this.length * 2L) + 45) / 8))
|
||||||
|
|
||||||
|
fun Boolean.bytesUsedInMemory(): Long = 8
|
||||||
|
|
||||||
fun String.containsIgnoreCase(term: String): Boolean {
|
fun String.containsIgnoreCase(term: String): Boolean {
|
||||||
if (term.isEmpty()) return true // Empty string is contained
|
if (term.isEmpty()) return true // Empty string is contained
|
||||||
|
|||||||
Reference in New Issue
Block a user