From 4dfc6525a154f81792db5e44cca095c36c9c198a Mon Sep 17 00:00:00 2001 From: Kieran Date: Mon, 11 Sep 2023 14:27:39 +0100 Subject: [PATCH] flat_merge to rust --- packages/system-query/Cargo.toml | 4 +- packages/system-query/pkg/system_query.d.ts | 6 + packages/system-query/pkg/system_query.js | 20 ++ .../system-query/pkg/system_query_bg.wasm | Bin 89560 -> 118793 bytes .../pkg/system_query_bg.wasm.d.ts | 1 + packages/system-query/src/expand.rs | 13 +- packages/system-query/src/filter.rs | 287 ++++++++++++++++++ packages/system-query/src/lib.rs | 100 ++---- packages/system-query/src/merge.rs | 214 +++++-------- packages/system/src/nostr-system.ts | 8 +- packages/system/src/request-builder.ts | 4 +- 11 files changed, 423 insertions(+), 234 deletions(-) create mode 100644 packages/system-query/src/filter.rs diff --git a/packages/system-query/Cargo.toml b/packages/system-query/Cargo.toml index 17f087dbf..fb15f8163 100644 --- a/packages/system-query/Cargo.toml +++ b/packages/system-query/Cargo.toml @@ -9,11 +9,11 @@ crate-type = ["cdylib"] [dependencies] itertools = "0.11.0" -rand = "0.8.5" serde = { version = "1.0.188", features = ["derive"] } serde-wasm-bindgen = "0.5.0" wasm-bindgen = "0.2.87" -serde_json = "1.0.105" [dev-dependencies] +rand = "0.8.5" wasm-bindgen-test = "0.3.37" +serde_json = "1.0.105" diff --git a/packages/system-query/pkg/system_query.d.ts b/packages/system-query/pkg/system_query.d.ts index 1b2449104..4b24908a0 100644 --- a/packages/system-query/pkg/system_query.d.ts +++ b/packages/system-query/pkg/system_query.d.ts @@ -17,6 +17,11 @@ export function expand_filter(val: any): any; * @returns {any} */ export function get_diff(prev: any, next: any): any; +/** +* @param {any} val +* @returns {any} +*/ +export function flat_merge(val: any): any; export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module; @@ -25,6 +30,7 @@ export interface InitOutput { readonly diff_filters: (a: number, b: number, c: number) => void; readonly expand_filter: (a: number, b: number) => void; readonly get_diff: (a: number, b: number, c: number) => void; + readonly flat_merge: (a: number, b: number) => void; readonly __wbindgen_malloc: (a: number, b: number) => number; readonly __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number; readonly __wbindgen_add_to_stack_pointer: (a: number) => number; diff --git a/packages/system-query/pkg/system_query.js b/packages/system-query/pkg/system_query.js index 2cb5f0aa0..9fb7deef2 100644 --- a/packages/system-query/pkg/system_query.js +++ b/packages/system-query/pkg/system_query.js @@ -250,6 +250,26 @@ export function get_diff(prev, next) { } } +/** +* @param {any} val +* @returns {any} +*/ +export function flat_merge(val) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.flat_merge(retptr, addHeapObject(val)); + var r0 = getInt32Memory0()[retptr / 4 + 0]; + var r1 = getInt32Memory0()[retptr / 4 + 1]; + var r2 = getInt32Memory0()[retptr / 4 + 2]; + if (r2) { + throw takeObject(r1); + } + return takeObject(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } +} + function handleError(f, args) { try { return f.apply(this, args); diff --git a/packages/system-query/pkg/system_query_bg.wasm b/packages/system-query/pkg/system_query_bg.wasm index 1a585083228ae3cf7c94f2dfd83a96e351b62f94..394d0f79785d2ed823f835286cfe364280ea8c71 100644 GIT binary patch literal 118793 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�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
  • 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 Pmhs*WFrK{F%J}~QB@!xO diff --git a/packages/system-query/pkg/system_query_bg.wasm.d.ts b/packages/system-query/pkg/system_query_bg.wasm.d.ts index ac811304a..506a78650 100644 --- a/packages/system-query/pkg/system_query_bg.wasm.d.ts +++ b/packages/system-query/pkg/system_query_bg.wasm.d.ts @@ -4,6 +4,7 @@ export const memory: WebAssembly.Memory; export function diff_filters(a: number, b: number, c: number): void; export function expand_filter(a: number, b: number): void; export function get_diff(a: number, b: number, c: number): void; +export function flat_merge(a: number, b: number): void; export function __wbindgen_malloc(a: number, b: number): number; export function __wbindgen_realloc(a: number, b: number, c: number, d: number): number; export function __wbindgen_add_to_stack_pointer(a: number): number; diff --git a/packages/system-query/src/expand.rs b/packages/system-query/src/expand.rs index 46eb37f34..4871a0fe8 100644 --- a/packages/system-query/src/expand.rs +++ b/packages/system-query/src/expand.rs @@ -161,14 +161,19 @@ pub fn expand_filter(filter: &ReqFilter) -> Vec { mod tests { use super::*; use crate::ReqFilter; + use std::collections::HashSet; #[test] fn test_expand_filter() { let input = ReqFilter { - authors: Some(vec!["a".to_owned(), "b".to_owned(), "c".to_owned()]), - kinds: Some(vec![1, 2, 3]), - ids: Some(vec!["x".to_owned(), "y".to_owned()]), - p_tag: Some(vec!["a".to_owned()]), + authors: Some(HashSet::from([ + "a".to_owned(), + "b".to_owned(), + "c".to_owned(), + ])), + kinds: Some(HashSet::from([1, 2, 3])), + ids: Some(HashSet::from(["x".to_owned(), "y".to_owned()])), + p_tag: Some(HashSet::from(["a".to_owned()])), t_tag: None, d_tag: None, r_tag: None, diff --git a/packages/system-query/src/filter.rs b/packages/system-query/src/filter.rs new file mode 100644 index 000000000..43f812ef6 --- /dev/null +++ b/packages/system-query/src/filter.rs @@ -0,0 +1,287 @@ +use serde::{Deserialize, Serialize}; +use std::collections::HashSet; +#[cfg(test)] +use std::fmt::Debug; +use std::hash::Hash; + +#[derive(PartialEq, Clone, Serialize, Deserialize)] +pub struct ReqFilter { + #[serde(rename = "ids", skip_serializing_if = "Option::is_none")] + pub ids: Option>, + #[serde(rename = "authors", skip_serializing_if = "Option::is_none")] + pub authors: Option>, + #[serde(rename = "kinds", skip_serializing_if = "Option::is_none")] + pub kinds: Option>, + #[serde(rename = "#e", skip_serializing_if = "Option::is_none")] + pub e_tag: Option>, + #[serde(rename = "#p", skip_serializing_if = "Option::is_none")] + pub p_tag: Option>, + #[serde(rename = "#t", skip_serializing_if = "Option::is_none")] + pub t_tag: Option>, + #[serde(rename = "#d", skip_serializing_if = "Option::is_none")] + pub d_tag: Option>, + #[serde(rename = "#r", skip_serializing_if = "Option::is_none")] + pub r_tag: Option>, + #[serde(rename = "search", skip_serializing_if = "Option::is_none")] + pub search: Option>, + #[serde(rename = "since", skip_serializing_if = "Option::is_none")] + pub since: Option, + #[serde(rename = "until", skip_serializing_if = "Option::is_none")] + pub until: Option, + #[serde(rename = "limit", skip_serializing_if = "Option::is_none")] + pub limit: Option, +} + +#[cfg(test)] +impl Debug for ReqFilter { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str(&serde_json::to_string(self).unwrap().to_owned()) + } +} + +#[derive(PartialEq, PartialOrd, Clone, Serialize, Deserialize)] +pub struct FlatReqFilter { + #[serde(rename = "ids", skip_serializing_if = "Option::is_none")] + pub id: Option, + #[serde(rename = "authors", skip_serializing_if = "Option::is_none")] + pub author: Option, + #[serde(rename = "kinds", skip_serializing_if = "Option::is_none")] + pub kind: Option, + #[serde(rename = "#e", skip_serializing_if = "Option::is_none")] + pub e_tag: Option, + #[serde(rename = "#p", skip_serializing_if = "Option::is_none")] + pub p_tag: Option, + #[serde(rename = "#t", skip_serializing_if = "Option::is_none")] + pub t_tag: Option, + #[serde(rename = "#d", skip_serializing_if = "Option::is_none")] + pub d_tag: Option, + #[serde(rename = "#r", skip_serializing_if = "Option::is_none")] + pub r_tag: Option, + #[serde(rename = "search", skip_serializing_if = "Option::is_none")] + pub search: Option, + #[serde(rename = "since", skip_serializing_if = "Option::is_none")] + pub since: Option, + #[serde(rename = "until", skip_serializing_if = "Option::is_none")] + pub until: Option, + #[serde(rename = "limit", skip_serializing_if = "Option::is_none")] + pub limit: Option, +} + +#[cfg(test)] +impl Debug for FlatReqFilter { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str(&serde_json::to_string(self).unwrap().to_owned()) + } +} + +pub trait Distance { + /// Calculate the distance in terms of similarity for merging + /// + /// The goal of this function is to find 2 filters which are very similar where + /// one filter may have a single property change like so: + /// + /// ```javascript + /// const a = { "kinds": 1, "authors": "a", "since": 99 }; + /// const b = { "kinds": 1, "authors": "b", "since": 99 }; + /// ``` + /// In this case these 2 filters could be merged because their distance is `1` + /// ```javascript + /// const result = { "kinds": [1], "authors": ["a", "b"], "since": 99 }; + /// ``` + fn distance(&self, other: &Self) -> u32; +} + +pub trait CanMerge { + fn can_merge(&self, other: &Self) -> bool; +} + +impl Distance for FlatReqFilter { + fn distance(&self, b: &Self) -> u32 { + let mut ret = 0u32; + + ret += prop_dist(&self.id, &b.id); + ret += prop_dist(&self.kind, &b.kind); + ret += prop_dist(&self.author, &b.author); + ret += prop_dist(&self.e_tag, &b.e_tag); + ret += prop_dist(&self.p_tag, &b.p_tag); + ret += prop_dist(&self.d_tag, &b.d_tag); + ret += prop_dist(&self.r_tag, &b.r_tag); + ret += prop_dist(&self.t_tag, &b.t_tag); + ret += prop_dist(&self.search, &b.search); + + ret + } +} + +impl CanMerge for FlatReqFilter { + fn can_merge(&self, other: &Self) -> bool { + if self.since != other.since + || self.until != other.until + || self.limit != other.limit + || self.search != other.search + { + return false; + } + + self.distance(other) <= 1 + } +} + +impl From> for ReqFilter { + fn from(value: Vec<&FlatReqFilter>) -> Self { + let ret = ReqFilter { + ids: None, + authors: None, + kinds: None, + e_tag: None, + p_tag: None, + t_tag: None, + d_tag: None, + r_tag: None, + search: None, + since: None, + until: None, + limit: None, + }; + value.iter().fold(ret, |mut acc, x| { + array_prop_append(&x.id, &mut acc.ids); + array_prop_append(&x.author, &mut acc.authors); + array_prop_append(&x.kind, &mut acc.kinds); + array_prop_append(&x.e_tag, &mut acc.e_tag); + array_prop_append(&x.p_tag, &mut acc.p_tag); + array_prop_append(&x.t_tag, &mut acc.t_tag); + array_prop_append(&x.d_tag, &mut acc.d_tag); + array_prop_append(&x.r_tag, &mut acc.r_tag); + array_prop_append(&x.search, &mut acc.search); + acc.since = x.since; + acc.until = x.until; + acc.limit = x.limit; + + acc + }) + } +} + +impl From> for ReqFilter { + fn from(value: Vec<&ReqFilter>) -> Self { + let ret = ReqFilter { + ids: None, + authors: None, + kinds: None, + e_tag: None, + p_tag: None, + t_tag: None, + d_tag: None, + r_tag: None, + search: None, + since: None, + until: None, + limit: None, + }; + value.iter().fold(ret, |mut acc, x| { + array_prop_append_vec(&x.ids, &mut acc.ids); + array_prop_append_vec(&x.authors, &mut acc.authors); + array_prop_append_vec(&x.kinds, &mut acc.kinds); + array_prop_append_vec(&x.e_tag, &mut acc.e_tag); + array_prop_append_vec(&x.p_tag, &mut acc.p_tag); + array_prop_append_vec(&x.t_tag, &mut acc.t_tag); + array_prop_append_vec(&x.d_tag, &mut acc.d_tag); + array_prop_append_vec(&x.r_tag, &mut acc.r_tag); + array_prop_append_vec(&x.search, &mut acc.search); + acc.since = x.since; + acc.until = x.until; + acc.limit = x.limit; + + acc + }) + } +} + +impl Distance for ReqFilter { + fn distance(&self, b: &Self) -> u32 { + let mut ret = 0u32; + + ret += prop_dist_vec(&self.ids, &b.ids); + ret += prop_dist_vec(&self.kinds, &b.kinds); + ret += prop_dist_vec(&self.authors, &b.authors); + ret += prop_dist_vec(&self.e_tag, &b.e_tag); + ret += prop_dist_vec(&self.p_tag, &b.p_tag); + ret += prop_dist_vec(&self.d_tag, &b.d_tag); + ret += prop_dist_vec(&self.r_tag, &b.r_tag); + ret += prop_dist_vec(&self.t_tag, &b.t_tag); + ret += prop_dist_vec(&self.search, &b.search); + + ret + } +} + +impl CanMerge for ReqFilter { + fn can_merge(&self, other: &Self) -> bool { + if self.since != other.since + || self.until != other.until + || self.limit != other.limit + || self.search != other.search + { + return false; + } + + self.distance(other) <= 1 + } +} + +#[inline(always)] +fn prop_dist(a: &Option, b: &Option) -> u32 { + if (a.is_some() && b.is_none()) || (a.is_none() && b.is_some()) { + return 10; + } else if a.is_some() && a != b { + return 1; + } + 0 +} + +#[inline(always)] +fn prop_dist_vec(a: &Option>, b: &Option>) -> u32 { + if (a.is_some() && b.is_none()) || (a.is_none() && b.is_some()) { + return 10; + } + match (a, b) { + (Some(aa), Some(bb)) => { + if aa.len() != bb.len() { + 1 + } else if aa == bb { + 0 + } else { + 1 + } + } + (None, None) => 0, + _ => panic!("Should not reach here!"), + } +} + +#[inline(always)] +fn array_prop_append(val: &Option, arr: &mut Option>) { + if let Some(ap) = val { + if arr.is_none() { + *arr = Some(HashSet::from([ap.clone()])) + } else { + arr.as_mut().unwrap().insert(ap.clone()); + } + } +} + +#[inline(always)] +fn array_prop_append_vec( + val: &Option>, + arr: &mut Option>, +) { + if let Some(ap) = val { + if arr.is_none() { + *arr = Some(ap.clone()) + } else { + ap.iter().for_each(|v| { + arr.as_mut().unwrap().insert((*v).clone()); + }); + } + } +} diff --git a/packages/system-query/src/lib.rs b/packages/system-query/src/lib.rs index 75a8f131c..0b1186088 100644 --- a/packages/system-query/src/lib.rs +++ b/packages/system-query/src/lib.rs @@ -1,79 +1,11 @@ -use std::fmt::{Debug}; -use serde::{Deserialize, Serialize}; +use crate::filter::{FlatReqFilter, ReqFilter}; use wasm_bindgen::prelude::*; mod diff; mod expand; +mod filter; mod merge; -#[derive(PartialEq, Clone, Serialize, Deserialize)] -pub struct ReqFilter { - #[serde(rename = "ids", skip_serializing_if = "Option::is_none")] - pub ids: Option>, - #[serde(rename = "authors", skip_serializing_if = "Option::is_none")] - pub authors: Option>, - #[serde(rename = "kinds", skip_serializing_if = "Option::is_none")] - pub kinds: Option>, - #[serde(rename = "#e", skip_serializing_if = "Option::is_none")] - pub e_tag: Option>, - #[serde(rename = "#p", skip_serializing_if = "Option::is_none")] - pub p_tag: Option>, - #[serde(rename = "#t", skip_serializing_if = "Option::is_none")] - pub t_tag: Option>, - #[serde(rename = "#d", skip_serializing_if = "Option::is_none")] - pub d_tag: Option>, - #[serde(rename = "#r", skip_serializing_if = "Option::is_none")] - pub r_tag: Option>, - #[serde(rename = "search", skip_serializing_if = "Option::is_none")] - pub search: Option>, - #[serde(rename = "since", skip_serializing_if = "Option::is_none")] - pub since: Option, - #[serde(rename = "until", skip_serializing_if = "Option::is_none")] - pub until: Option, - #[serde(rename = "limit", skip_serializing_if = "Option::is_none")] - pub limit: Option, -} - -impl Debug for ReqFilter { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.write_str(&serde_json::to_string(self).unwrap().to_owned()) - } -} - -#[derive(PartialEq, Clone, Serialize, Deserialize)] -pub struct FlatReqFilter { - #[serde(rename = "ids", skip_serializing_if = "Option::is_none")] - id: Option, - #[serde(rename = "authors", skip_serializing_if = "Option::is_none")] - author: Option, - #[serde(rename = "kinds", skip_serializing_if = "Option::is_none")] - kind: Option, - #[serde(rename = "#e", skip_serializing_if = "Option::is_none")] - e_tag: Option, - #[serde(rename = "#p", skip_serializing_if = "Option::is_none")] - p_tag: Option, - #[serde(rename = "#t", skip_serializing_if = "Option::is_none")] - t_tag: Option, - #[serde(rename = "#d", skip_serializing_if = "Option::is_none")] - d_tag: Option, - #[serde(rename = "#r", skip_serializing_if = "Option::is_none")] - r_tag: Option, - #[serde(rename = "search", skip_serializing_if = "Option::is_none")] - search: Option, - #[serde(rename = "since", skip_serializing_if = "Option::is_none")] - since: Option, - #[serde(rename = "until", skip_serializing_if = "Option::is_none")] - until: Option, - #[serde(rename = "limit", skip_serializing_if = "Option::is_none")] - limit: Option, -} - -impl Debug for FlatReqFilter { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.write_str(&serde_json::to_string(self).unwrap().to_owned()) - } -} - #[wasm_bindgen] pub fn diff_filters(prev: JsValue, next: JsValue) -> Result { let prev_parsed: Vec = serde_wasm_bindgen::from_value(prev)?; @@ -108,7 +40,7 @@ pub fn get_diff(prev: JsValue, next: JsValue) -> Result { #[wasm_bindgen] pub fn flat_merge(val: JsValue) -> Result { let val_parsed: Vec = serde_wasm_bindgen::from_value(val)?; - let result = merge::flat_merge(&val_parsed); + let result = merge::merge::(val_parsed.iter().collect()); Ok(serde_wasm_bindgen::to_value(&result)?) } @@ -117,25 +49,26 @@ mod tests { use super::*; use itertools::Itertools; use std::cmp::Ordering; + use std::collections::HashSet; #[test] fn flat_merge_expanded() { let input = vec![ ReqFilter { ids: None, - kinds: Some(vec![1, 6969, 6]), + kinds: Some(HashSet::from([1, 6969, 6])), e_tag: None, p_tag: None, t_tag: None, d_tag: None, r_tag: None, - authors: Some(vec![ + authors: Some(HashSet::from([ "kieran".to_string(), "snort".to_string(), "c".to_string(), "d".to_string(), "e".to_string(), - ]), + ])), since: Some(1), until: Some(100), search: None, @@ -143,7 +76,7 @@ mod tests { }, ReqFilter { ids: None, - kinds: Some(vec![4]), + kinds: Some(HashSet::from([4])), e_tag: None, p_tag: None, t_tag: None, @@ -152,15 +85,15 @@ mod tests { search: None, since: None, until: None, - authors: Some(vec!["kieran".to_string()]), + authors: Some(HashSet::from(["kieran".to_string()])), limit: None, }, ReqFilter { ids: None, authors: None, - kinds: Some(vec![4]), + kinds: Some(HashSet::from([4])), e_tag: None, - p_tag: Some(vec!["kieran".to_string()]), + p_tag: Some(HashSet::from(["kieran".to_string()])), t_tag: None, d_tag: None, r_tag: None, @@ -171,9 +104,9 @@ mod tests { }, ReqFilter { ids: None, - kinds: Some(vec![1000]), - authors: Some(vec!["snort".to_string()]), - p_tag: Some(vec!["kieran".to_string()]), + kinds: Some(HashSet::from([1000])), + authors: Some(HashSet::from(["snort".to_string()])), + p_tag: Some(HashSet::from(["kieran".to_string()])), t_tag: None, d_tag: None, r_tag: None, @@ -196,7 +129,8 @@ mod tests { } }) .collect_vec(); - let expanded_flat = merge::flat_merge(&expanded); - assert_eq!(expanded_flat, input); + let merged_expanded: Vec = merge::merge(expanded.iter().collect()); + assert_eq!(merged_expanded.len(), input.len()); + assert!(merged_expanded.iter().all(|v| input.contains(v))); } } diff --git a/packages/system-query/src/merge.rs b/packages/system-query/src/merge.rs index 47a8ba815..3b2455789 100644 --- a/packages/system-query/src/merge.rs +++ b/packages/system-query/src/merge.rs @@ -1,134 +1,59 @@ -use crate::{FlatReqFilter, ReqFilter}; -use itertools::Itertools; -use std::cmp::Ordering; +use crate::filter::CanMerge; -pub fn flat_merge(all: &Vec) -> Vec { - let mut ret: Vec = vec![]; - - let merge_sets: Vec> = vec![vec![all.first().unwrap()]]; - let merge_sets = all - .iter() - .skip(1) - .sorted_by(|a, b| match distance(&a, &b) { - 0 => Ordering::Equal, - 1 => Ordering::Less, - _ => Ordering::Greater, - }) - .fold(merge_sets, |mut acc, x| { - let mut did_match = false; - for y in acc.iter_mut() { - if y.iter().all(|z| can_merge_filters(z, x)) { - y.push(x); - did_match = true; - break; - } - } - if !did_match { - acc.push(vec![x]); - } - acc - }); - - for s in merge_sets.iter() { - ret.push(merge_set(s)); - } - ret -} - -fn merge_set(set: &Vec<&FlatReqFilter>) -> ReqFilter { - let ret = ReqFilter { - ids: None, - authors: None, - kinds: None, - e_tag: None, - p_tag: None, - t_tag: None, - d_tag: None, - r_tag: None, - search: None, - since: None, - until: None, - limit: None, - }; - set.iter().fold(ret, |mut acc, x| { - array_prop_append(&x.id, &mut acc.ids); - array_prop_append(&x.author, &mut acc.authors); - array_prop_append(&x.kind, &mut acc.kinds); - array_prop_append(&x.e_tag, &mut acc.e_tag); - array_prop_append(&x.p_tag, &mut acc.p_tag); - array_prop_append(&x.t_tag, &mut acc.t_tag); - array_prop_append(&x.d_tag, &mut acc.d_tag); - array_prop_append(&x.r_tag, &mut acc.r_tag); - array_prop_append(&x.search, &mut acc.search); - acc.since = x.since; - acc.until = x.until; - acc.limit = x.limit; - - acc - }) -} - -fn can_merge_filters(a: &FlatReqFilter, b: &FlatReqFilter) -> bool { - if a.since != b.since || a.until != b.until || a.limit != b.limit || a.search != b.search { - return false; - } - - distance(a, b) <= 1 -} - -/// Calculate the distance in terms of similarity for merging -/// -/// The goal of this function is to find 2 filters which are very similar where -/// one filter may have a single property change like so: -/// -/// ```javascript -/// const a = { "kinds": 1, "authors": "a", "since": 99 }; -/// const b = { "kinds": 1, "authors": "b", "since": 99 }; -/// ``` -/// In this case these 2 filters could be merged because their distance is `1` -/// ```javascript -/// const result = { "kinds": [1], "authors": ["a", "b"], "since": 99 }; -/// ``` -fn distance(a: &FlatReqFilter, b: &FlatReqFilter) -> u32 { - let mut ret = 0u32; - - ret += prop_dist(&a.id, &b.id); - ret += prop_dist(&a.kind, &b.kind); - ret += prop_dist(&a.author, &b.author); - ret += prop_dist(&a.e_tag, &b.e_tag); - ret += prop_dist(&a.p_tag, &b.p_tag); - ret += prop_dist(&a.d_tag, &b.d_tag); - ret += prop_dist(&a.r_tag, &b.r_tag); - ret += prop_dist(&a.t_tag, &b.t_tag); - ret += prop_dist(&a.search, &b.search); - - ret -} - -#[inline(always)] -fn prop_dist(a: &Option, b: &Option) -> u32 { - if (a.is_some() && b.is_none()) || (a.is_none() && b.is_some()) { - return 10; - } else if a.is_some() && a != b { - return 1; - } - 0 -} - -#[inline(always)] -fn array_prop_append(val: &Option, arr: &mut Option>) { - if let Some(ap) = val { - if arr.is_none() { - *arr = Some(vec![ap.clone()]) - } else if !arr.as_ref().unwrap().contains(ap) { - arr.as_mut().unwrap().push(ap.clone()); +pub fn merge<'a, T, Z>(all: Vec<&'a T>) -> Vec +where + T: CanMerge, + for<'b> Z: CanMerge + From> + From>, +{ + let mut ret: Vec = merge_once(all); + loop { + let last_len = ret.len(); + ret = merge_once(ret.iter().collect()); + if last_len == ret.len() { + break; } } + ret +} + +fn merge_once<'a, T, Z>(all: Vec<&'a T>) -> Vec +where + T: CanMerge, + for<'b> Z: CanMerge + From> + From>, +{ + let mut ret: Vec = vec![]; + if all.is_empty() { + return ret; + } + + let merge_sets: Vec> = vec![vec![all.first().unwrap()]]; + let merge_sets = all.iter().skip(1).fold(merge_sets, |mut acc, x| { + let mut did_match = false; + for y in acc.iter_mut() { + if y.iter().all(|z| z.can_merge(x)) { + y.push(x); + did_match = true; + break; + } + } + if !did_match { + acc.push(vec![x]); + } + acc + }); + + for s in merge_sets { + ret.push(Z::from(s)); + } + + ret } #[cfg(test)] mod tests { use super::*; + use crate::filter::{Distance, FlatReqFilter, ReqFilter}; + use std::collections::HashSet; #[test] fn distance() { @@ -202,10 +127,10 @@ mod tests { until: None, limit: None, }; - assert_eq!(super::distance(&a, &b), 0); - assert_eq!(super::distance(&a, &c), 1); - assert_eq!(super::distance(&a, &d), 10); - assert_eq!(super::distance(&a, &e), 11); + assert_eq!(a.distance(&b), 0); + assert_eq!(a.distance(&c), 1); + assert_eq!(a.distance(&d), 10); + assert_eq!(a.distance(&e), 11); } #[test] @@ -240,8 +165,8 @@ mod tests { }; let output = ReqFilter { - ids: Some(vec!["0".to_owned()]), - authors: Some(vec!["a".to_owned(), "b".to_owned()]), + ids: Some(HashSet::from(["0".to_owned()])), + authors: Some(HashSet::from(["a".to_owned(), "b".to_owned()])), kinds: None, e_tag: None, p_tag: None, @@ -253,7 +178,7 @@ mod tests { until: None, limit: Some(10), }; - assert_eq!(super::merge_set(&vec![&a, &b]), output); + assert_eq!(ReqFilter::from(vec![&a, &b]), output); } #[test] @@ -300,8 +225,8 @@ mod tests { until: None, limit: Some(100), }; - assert!(super::can_merge_filters(&a, &b)); - assert!(!super::can_merge_filters(&b, &c)); + assert!(&a.can_merge(&b)); + assert!(!&b.can_merge(&c)); } #[test] @@ -436,8 +361,12 @@ mod tests { ]; let output = vec![ ReqFilter { - ids: Some(vec!["0".to_owned()]), - authors: Some(vec!["a".to_owned(), "b".to_owned(), "c".to_owned()]), + ids: Some(HashSet::from(["0".to_owned()])), + authors: Some(HashSet::from([ + "a".to_owned(), + "b".to_owned(), + "c".to_owned(), + ])), kinds: None, e_tag: None, p_tag: None, @@ -452,7 +381,7 @@ mod tests { ReqFilter { ids: None, authors: None, - kinds: Some(vec![1, 2]), + kinds: Some(HashSet::from([1, 2])), e_tag: None, p_tag: None, t_tag: None, @@ -465,8 +394,8 @@ mod tests { }, ReqFilter { ids: None, - authors: Some(vec!["c".to_owned()]), - kinds: Some(vec![1]), + authors: Some(HashSet::from(["c".to_owned()])), + kinds: Some(HashSet::from([1])), e_tag: None, p_tag: None, t_tag: None, @@ -479,7 +408,7 @@ mod tests { }, ReqFilter { ids: None, - authors: Some(vec!["c".to_owned()]), + authors: Some(HashSet::from(["c".to_owned()])), kinds: None, e_tag: None, p_tag: None, @@ -492,8 +421,8 @@ mod tests { limit: Some(100), }, ReqFilter { - ids: Some(vec!["1".to_owned()]), - authors: Some(vec!["c".to_owned()]), + ids: Some(HashSet::from(["1".to_owned()])), + authors: Some(HashSet::from(["c".to_owned()])), kinds: None, e_tag: None, p_tag: None, @@ -507,6 +436,9 @@ mod tests { }, ]; - assert_eq!(super::flat_merge(&input), output) + assert_eq!( + merge::(input.iter().collect()), + output + ) } } diff --git a/packages/system/src/nostr-system.ts b/packages/system/src/nostr-system.ts index 90f8ecf68..ec22de6c6 100644 --- a/packages/system/src/nostr-system.ts +++ b/packages/system/src/nostr-system.ts @@ -4,7 +4,7 @@ import { unwrap, sanitizeRelayUrl, ExternalStore, FeedCache } from "@snort/share import { NostrEvent, TaggedNostrEvent } from "./nostr"; import { AuthHandler, Connection, RelaySettings, ConnectionStateSnapshot } from "./connection"; import { Query } from "./query"; -import { NoteCollection, NoteStore, NoteStoreHook, NoteStoreSnapshotData } from "./note-collection"; +import { NoteCollection, NoteStore, NoteStoreSnapshotData } from "./note-collection"; import { BuiltRawReqFilter, RequestBuilder } from "./request-builder"; import { RelayMetricHandler } from "./relay-metric-handler"; import { @@ -258,8 +258,12 @@ export class NostrSystem extends ExternalStore implements System const filters = req.build(this.#relayCache); const q = new Query(req.id, req.instance, store, req.options?.leaveOpen); if (filters.some(a => a.filters.some(b => b.ids))) { + const expectIds = new Set(filters.flatMap(a => a.filters).flatMap(a => a.ids ?? [])); q.feed.onEvent(async evs => { - await this.#eventsCache.bulkSet(evs); + const toSet = evs.filter(a => expectIds.has(a.id) && this.#eventsCache.getFromCache(a.id) === undefined); + if(toSet.length > 0) { + await this.#eventsCache.bulkSet(toSet); + } }); } this.Queries.set(req.id, q); diff --git a/packages/system/src/request-builder.ts b/packages/system/src/request-builder.ts index 311d41e57..9a7c49aad 100644 --- a/packages/system/src/request-builder.ts +++ b/packages/system/src/request-builder.ts @@ -1,7 +1,7 @@ import debug from "debug"; import { v4 as uuid } from "uuid"; import { appendDedupe, sanitizeRelayUrl, unixNowMs } from "@snort/shared"; -import { get_diff }from "@snort/system-query"; +import { flat_merge, get_diff }from "@snort/system-query"; import { ReqFilter, u256, HexKey, EventKind } from "."; import { RelayCache, splitByWriteRelays, splitFlatByWriteRelays } from "./gossip-model"; @@ -115,7 +115,7 @@ export class RequestBuilder { return splitFlatByWriteRelays(relays, diff).map(a => { return { strategy: RequestStrategy.AuthorsRelays, - filters: flatMerge(a.filters), + filters: flat_merge(a.filters) as Array, relay: a.relay, }; });