perf: dont create intermediate vecs when matching subs

Avoid creating intermediate vectors when matching subscriptions. We can
just iterate over the hashmap directly.
This commit is contained in:
William Casarin 2022-11-08 18:02:27 -08:00 committed by Greg Heartsfield
parent 9dd4571bee
commit 7adc5c9af7
2 changed files with 9 additions and 15 deletions

View File

@ -2,7 +2,6 @@
use crate::close::Close; use crate::close::Close;
use crate::error::Error; use crate::error::Error;
use crate::error::Result; use crate::error::Result;
use crate::event::Event;
use crate::subscription::Subscription; use crate::subscription::Subscription;
use std::collections::HashMap; use std::collections::HashMap;
@ -43,6 +42,10 @@ impl ClientConn {
} }
} }
pub fn subscriptions(&self) -> &HashMap<String, Subscription> {
&self.subscriptions
}
/// Get a short prefix of the client's unique identifier, suitable /// Get a short prefix of the client's unique identifier, suitable
/// for logging. /// for logging.
#[must_use] #[must_use]
@ -55,18 +58,6 @@ impl ClientConn {
&self.client_ip &self.client_ip
} }
/// Find all matching subscriptions.
#[must_use]
pub fn get_matching_subscriptions(&self, e: &Event) -> Vec<&str> {
let mut v: Vec<&str> = vec![];
for (id, sub) in &self.subscriptions {
if sub.interested_in_event(e) {
v.push(id);
}
}
v
}
/// Add a new subscription for this connection. /// Add a new subscription for this connection.
/// # Errors /// # Errors
/// ///

View File

@ -499,8 +499,11 @@ async fn nostr_server(
Ok(global_event) = bcast_rx.recv() => { Ok(global_event) = bcast_rx.recv() => {
// an event has been broadcast to all clients // an event has been broadcast to all clients
// first check if there is a subscription for this event. // first check if there is a subscription for this event.
let matching_subs = conn.get_matching_subscriptions(&global_event); for (s, sub) in conn.subscriptions() {
for s in matching_subs { if !sub.interested_in_event(&global_event) {
continue;
}
// TODO: serialize at broadcast time, instead of // TODO: serialize at broadcast time, instead of
// once for each consumer. // once for each consumer.
if let Ok(event_str) = serde_json::to_string(&global_event) { if let Ok(event_str) = serde_json::to_string(&global_event) {