From eab41a798dc88e6218dbdd07145eec85b39db35a Mon Sep 17 00:00:00 2001 From: Yuki Kishimoto Date: Tue, 1 Oct 2024 12:02:13 -0400 Subject: [PATCH] nostr: move `TagsIndexes` into `Tags` struct Signed-off-by: Yuki Kishimoto --- CHANGELOG.md | 1 + crates/nostr/src/event/mod.rs | 35 +++------------- crates/nostr/src/event/tag/list.rs | 67 ++++++++++++++++++++++++++++-- crates/nostr/src/types/filter.rs | 8 ++-- 4 files changed, 74 insertions(+), 37 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 781d02384..b2692a7a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,7 @@ ### Changed +* nostr: move `TagsIndexes` into `Tags` struct ([Yuki Kishimoto]) * relay-builder: refactor `Session::check_rate_limit` method ([Yuki Kishimoto]) * pool: changes in `RelayPool::remove_relay` behavior ([Yuki Kishimoto]) * pool: deprecate `RelayPool::remove_all_relays` ([Yuki Kishimoto]) diff --git a/crates/nostr/src/event/mod.rs b/crates/nostr/src/event/mod.rs index 9b66b03b8..f6ef53665 100644 --- a/crates/nostr/src/event/mod.rs +++ b/crates/nostr/src/event/mod.rs @@ -6,7 +6,6 @@ //! Event use alloc::borrow::Cow; -use alloc::collections::{BTreeMap, BTreeSet}; use alloc::string::{String, ToString}; use alloc::vec::Vec; use core::cmp::Ordering; @@ -16,8 +15,6 @@ use core::str::FromStr; use bitcoin::secp256k1::schnorr::Signature; use bitcoin::secp256k1::{Message, Secp256k1, Verification}; -#[cfg(feature = "std")] -use once_cell::sync::OnceCell; // TODO: when MSRV will be >= 1.70.0, use `std::cell::OnceLock` instead and remove `once_cell` dep. use serde::ser::SerializeStruct; use serde::{Deserialize, Deserializer, Serialize, Serializer}; use serde_json::Value; @@ -34,6 +31,8 @@ pub use self::builder::EventBuilder; pub use self::id::EventId; pub use self::kind::Kind; pub use self::partial::{MissingPartialEvent, PartialEvent}; +#[cfg(feature = "std")] +use self::tag::list::TagsIndexes; pub use self::tag::{Tag, TagKind, TagStandard, Tags}; pub use self::unsigned::UnsignedEvent; use crate::nips::nip01::Coordinate; @@ -43,10 +42,7 @@ use crate::types::time::Instant; use crate::types::time::TimeSupplier; #[cfg(feature = "std")] use crate::SECP256K1; -use crate::{JsonUtil, Metadata, PublicKey, SingleLetterTag, Timestamp}; - -/// Tags Indexes -pub type TagsIndexes = BTreeMap>; +use crate::{JsonUtil, Metadata, PublicKey, Timestamp}; const ID: &str = "id"; const PUBKEY: &str = "pubkey"; @@ -108,9 +104,6 @@ pub struct Event { pub sig: Signature, /// JSON de/serialization order deser_order: Vec, - /// Tags indexes - #[cfg(feature = "std")] - tags_indexes: OnceCell, } impl fmt::Debug for Event { @@ -195,8 +188,6 @@ impl Event { content: content.into(), sig, deser_order: Vec::new(), - #[cfg(feature = "std")] - tags_indexes: OnceCell::new(), } } @@ -360,25 +351,11 @@ impl Event { self.tags.hashtags() } - pub(crate) fn build_tags_indexes(&self) -> TagsIndexes { - let mut idx: TagsIndexes = TagsIndexes::new(); - for (single_letter_tag, content) in self - .tags - .iter() - .filter_map(|t| Some((t.single_letter_tag()?, t.content()?))) - { - idx.entry(single_letter_tag) - .or_default() - .insert(content.to_string()); - } - idx - } - /// Get tags indexes - #[inline] + #[deprecated(since = "0.36.0", note = "Use `Tags::indexes` method instead.")] #[cfg(feature = "std")] pub fn tags_indexes(&self) -> &TagsIndexes { - self.tags_indexes.get_or_init(|| self.build_tags_indexes()) + self.tags.indexes() } /// Check if it's a protected event @@ -522,8 +499,6 @@ impl<'de> Deserialize<'de> for Event { content: inter.content.into_owned(), sig: inter.sig.into_owned(), deser_order, - #[cfg(feature = "std")] - tags_indexes: OnceCell::new(), }) } } diff --git a/crates/nostr/src/event/tag/list.rs b/crates/nostr/src/event/tag/list.rs index 1b8387746..587057f81 100644 --- a/crates/nostr/src/event/tag/list.rs +++ b/crates/nostr/src/event/tag/list.rs @@ -4,21 +4,32 @@ //! Tags (tag list) +use alloc::collections::{BTreeMap, BTreeSet}; +use alloc::string::{String, ToString}; use alloc::vec::{IntoIter, Vec}; +use core::cmp::Ordering; use core::fmt; +use core::hash::{Hash, Hasher}; use core::slice::Iter; +#[cfg(feature = "std")] +use once_cell::sync::OnceCell; // TODO: when MSRV will be >= 1.70.0, use `std::cell::OnceLock` instead and remove `once_cell` dep. use serde::ser::SerializeSeq; use serde::{Deserialize, Deserializer, Serialize, Serializer}; use super::Tag; use crate::nips::nip01::Coordinate; -use crate::{EventId, PublicKey, TagKind, TagStandard, Timestamp}; +use crate::{EventId, PublicKey, SingleLetterTag, TagKind, TagStandard, Timestamp}; + +/// Tags Indexes +pub type TagsIndexes = BTreeMap>; /// Tag list -#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[derive(Clone)] pub struct Tags { list: Vec, + #[cfg(feature = "std")] + indexes: OnceCell, } impl fmt::Debug for Tags { @@ -27,11 +38,41 @@ impl fmt::Debug for Tags { } } +impl PartialEq for Tags { + fn eq(&self, other: &Self) -> bool { + self.list == other.list + } +} + +impl Eq for Tags {} + +impl PartialOrd for Tags { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl Ord for Tags { + fn cmp(&self, other: &Self) -> Ordering { + self.list.cmp(&other.list) + } +} + +impl Hash for Tags { + fn hash(&self, state: &mut H) { + self.list.hash(state); + } +} + impl Tags { /// Construct new tag list. #[inline] pub fn new(list: Vec) -> Self { - Self { list } + Self { + list, + #[cfg(feature = "std")] + indexes: OnceCell::new(), + } } /// Get number of tags. @@ -180,6 +221,26 @@ impl Tags { _ => None, }) } + + pub(crate) fn build_indexes(&self) -> TagsIndexes { + let mut idx: TagsIndexes = TagsIndexes::new(); + for (single_letter_tag, content) in self + .iter() + .filter_map(|t| Some((t.single_letter_tag()?, t.content()?))) + { + idx.entry(single_letter_tag) + .or_default() + .insert(content.to_string()); + } + idx + } + + /// Get indexes + #[inline] + #[cfg(feature = "std")] + pub fn indexes(&self) -> &TagsIndexes { + self.indexes.get_or_init(|| self.build_indexes()) + } } impl AsRef<[Tag]> for Tags { diff --git a/crates/nostr/src/types/filter.rs b/crates/nostr/src/types/filter.rs index 08b47433b..7824599c2 100644 --- a/crates/nostr/src/types/filter.rs +++ b/crates/nostr/src/types/filter.rs @@ -15,7 +15,7 @@ use serde::de::{Deserializer, MapAccess, Visitor}; use serde::ser::{SerializeMap, Serializer}; use serde::{Deserialize, Serialize}; -use crate::event::TagsIndexes; +use crate::event::tag::list::TagsIndexes; use crate::nips::nip01::Coordinate; use crate::{Event, EventId, JsonUtil, Kind, PublicKey, Timestamp}; @@ -738,13 +738,13 @@ impl Filter { } #[cfg(feature = "std")] - let tags_indexes: &TagsIndexes = event.tags_indexes(); + let indexes: &TagsIndexes = event.tags.indexes(); #[cfg(not(feature = "std"))] - let tags_indexes: TagsIndexes = event.build_tags_indexes(); + let indexes: TagsIndexes = event.tags.build_indexes(); // Match self.generic_tags.iter().all(|(tag_name, set)| { - if let Some(val_set) = tags_indexes.get(tag_name) { + if let Some(val_set) = indexes.get(tag_name) { set.iter().any(|t| val_set.contains(t)) } else { false