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
|
||||
/// from a contact list
|
||||
pub fn filter_from_tags(
|
||||
|
||||
Reference in New Issue
Block a user