HyperLogLog support (NIP-45 PR #1561)

This commit is contained in:
Mike Dilger 2024-12-11 09:01:10 +13:00
parent c96b1d590e
commit 964d68de57
No known key found for this signature in database
GPG Key ID: 47581A78D4329BA4
2 changed files with 23 additions and 5 deletions

View File

@ -4,7 +4,7 @@ use crate::reply::{NostrReply, NostrReplyPrefix};
use crate::WebSocketService;
use hyper_tungstenite::tungstenite::Message;
use pocket_types::json::{eat_whitespace, json_unescape, verify_char};
use pocket_types::{Event, Filter, Kind, OwnedFilter, Pubkey, Time};
use pocket_types::{Event, Filter, Hll8, Kind, OwnedFilter, Pubkey, Time};
use url::Url;
impl WebSocketService {
@ -170,7 +170,18 @@ impl WebSocketService {
events.dedup();
if count {
let reply = NostrReply::Count(subid, events.len());
// HyperLogLog count
let mut opthll: Option<Hll8> = None;
if filters.len() == 1 {
if let Ok(Some(offset)) = filters[0].hyperloglog_offset() {
let mut hll8 = Hll8::new();
for event in events.iter() {
hll8.add_element(event.pubkey().as_bytes(), offset)?;
}
opthll = Some(hll8);
}
}
let reply = NostrReply::Count(subid, events.len(), opthll);
self.send(Message::text(reply.as_json())).await?;
} else {
for event in events.drain(..) {

View File

@ -1,4 +1,4 @@
use pocket_types::{Event, Id};
use pocket_types::{Event, Hll8, Id};
use std::fmt;
pub enum NostrReplyPrefix {
@ -36,7 +36,7 @@ pub enum NostrReply<'a> {
Eose(&'a str),
Closed(&'a str, NostrReplyPrefix, String),
Notice(String),
Count(&'a str, usize),
Count(&'a str, usize, Option<Hll8>),
}
impl NostrReply<'_> {
@ -50,7 +50,14 @@ impl NostrReply<'_> {
format!(r#"["CLOSED","{subid}","{prefix}{msg}"]"#)
}
NostrReply::Notice(msg) => format!(r#"["NOTICE","{msg}"]"#),
NostrReply::Count(subid, c) => format!(r#"["COUNT","{subid}",{{"count":{c}}}"#),
NostrReply::Count(subid, c, opthll) => {
if let Some(hll) = opthll {
let hll = hll.to_hex_string();
format!(r#"["COUNT","{subid}",{{"count":{c}, "hll":"{hll}"}}]"#)
} else {
format!(r#"["COUNT","{subid}",{{"count":{c}}}]"#)
}
}
}
}
}