algos: introduce last_n_per_pubkey_from_tags
This function creates filters for the base our first algo in Damus:
Called "last N note per pubkey". I don't have a better name for it.
This function generates a query in the form:
[
{"authors": ["author_a"], "limit": 1, "kinds": [1]
, {"authors": ["author_b"], "limit": 1, "kinds": [1]
, {"authors": ["author_c"], "limit": 1, "kinds": [1]
, {"authors": ["author_c"], "limit": 1, "kinds": [1]
...
]
Due to an unfortunate restriction currently in nostrdb and strfry, we
can only do about 16 to 20 of these at any given time. I have made
this limit configurable in strfry[1]. I just need to do the same in
nostrdb now.
[1] https://github.com/hoytech/strfry/pull/133
Changelog-Added: Add last_n_per_pubkey_from_tags algo function
This commit is contained in:
@@ -190,6 +190,60 @@ impl FilteredTags {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create a "last N notes per pubkey" query.
|
||||||
|
pub fn last_n_per_pubkey_from_tags(
|
||||||
|
note: &Note,
|
||||||
|
kind: u64,
|
||||||
|
notes_per_pubkey: u64,
|
||||||
|
) -> Result<Vec<Filter>> {
|
||||||
|
let mut filters: Vec<Filter> = vec![];
|
||||||
|
|
||||||
|
for tag in note.tags() {
|
||||||
|
// TODO: fix arbitrary MAX_FILTER limit in nostrdb
|
||||||
|
if filters.len() == 15 {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if tag.count() < 2 {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let t = if let Some(t) = tag.get_unchecked(0).variant().str() {
|
||||||
|
t
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
if t == "p" {
|
||||||
|
let author = if let Some(author) = tag.get_unchecked(1).variant().id() {
|
||||||
|
author
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut filter = Filter::new();
|
||||||
|
filter.start_authors_field()?;
|
||||||
|
filter.add_id_element(author)?;
|
||||||
|
filter.end_field();
|
||||||
|
filters.push(filter.kinds([kind]).limit(notes_per_pubkey).build());
|
||||||
|
} else if t == "t" {
|
||||||
|
let hashtag = if let Some(hashtag) = tag.get_unchecked(1).variant().str() {
|
||||||
|
hashtag
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut filter = Filter::new();
|
||||||
|
filter.start_tags_field('t')?;
|
||||||
|
filter.add_str_element(hashtag)?;
|
||||||
|
filter.end_field();
|
||||||
|
filters.push(filter.kinds([kind]).limit(notes_per_pubkey).build());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(filters)
|
||||||
|
}
|
||||||
|
|
||||||
/// Create a filter from tags. This can be used to create a filter
|
/// Create a filter from tags. This can be used to create a filter
|
||||||
/// from a contact list
|
/// from a contact list
|
||||||
pub fn filter_from_tags(
|
pub fn filter_from_tags(
|
||||||
|
|||||||
Reference in New Issue
Block a user