Skip to content

Commit 3260fa1

Browse files
committed
add authors query plan
This fixes author queries Fixes: #52 Signed-off-by: William Casarin <[email protected]>
1 parent 08c64ae commit 3260fa1

File tree

1 file changed

+95
-7
lines changed

1 file changed

+95
-7
lines changed

src/nostrdb.c

Lines changed: 95 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3139,6 +3139,85 @@ static int ndb_encode_tag_key(unsigned char *buf, int buf_size,
31393139
return writer.p - writer.start;
31403140
}
31413141

3142+
static int ndb_query_plan_execute_authors(struct ndb_txn *txn,
3143+
struct ndb_filter *filter,
3144+
struct ndb_query_results *results,
3145+
int limit)
3146+
{
3147+
MDB_val k, v;
3148+
MDB_cursor *cur;
3149+
int rc, i;
3150+
uint64_t *pint, until, since, note_key;
3151+
unsigned char *author;
3152+
struct ndb_note *note;
3153+
size_t note_size;
3154+
struct ndb_filter_elements *authors;
3155+
struct ndb_query_result res;
3156+
struct ndb_tsid tsid, *ptsid;
3157+
enum ndb_dbs db;
3158+
3159+
db = txn->lmdb->dbs[NDB_DB_NOTE_PUBKEY];
3160+
3161+
if (!(authors = ndb_filter_find_elements(filter, NDB_FILTER_AUTHORS)))
3162+
return 0;
3163+
3164+
until = UINT64_MAX;
3165+
if ((pint = ndb_filter_get_int(filter, NDB_FILTER_UNTIL)))
3166+
until = *pint;
3167+
3168+
since = 0;
3169+
if ((pint = ndb_filter_get_int(filter, NDB_FILTER_SINCE)))
3170+
since = *pint;
3171+
3172+
if ((rc = mdb_cursor_open(txn->mdb_txn, db, &cur)))
3173+
return 0;
3174+
3175+
for (i = 0; i < authors->count; i++) {
3176+
author = ndb_filter_get_id_element(filter, authors, i);
3177+
3178+
ndb_tsid_init(&tsid, author, until);
3179+
3180+
k.mv_data = &tsid;
3181+
k.mv_size = sizeof(tsid);
3182+
3183+
if (!ndb_cursor_start(cur, &k, &v))
3184+
continue;
3185+
3186+
// for each id in our ids filter, find in the db
3187+
while (!query_is_full(results, limit)) {
3188+
ptsid = (struct ndb_tsid *)k.mv_data;
3189+
note_key = *(uint64_t*)v.mv_data;
3190+
3191+
// don't continue the scan if we're below `since`
3192+
if (ptsid->timestamp < since)
3193+
break;
3194+
3195+
// our author should match, if not bail
3196+
if (memcmp(author, ptsid->id, 32))
3197+
break;
3198+
3199+
// fetch the note, we need it for our query results
3200+
// and to match further against the filter
3201+
if (!(note = ndb_get_note_by_key(txn, note_key, &note_size)))
3202+
goto next;
3203+
3204+
if (!ndb_filter_matches_with(filter, note, 1 << NDB_FILTER_AUTHORS))
3205+
goto next;
3206+
3207+
ndb_query_result_init(&res, note, note_size, note_key);
3208+
if (!push_query_result(results, &res))
3209+
break;
3210+
3211+
next:
3212+
if (mdb_cursor_get(cur, &k, &v, MDB_PREV))
3213+
break;
3214+
}
3215+
}
3216+
3217+
mdb_cursor_close(cur);
3218+
return 1;
3219+
}
3220+
31423221
static int ndb_query_plan_execute_created_at(struct ndb_txn *txn,
31433222
struct ndb_filter *filter,
31443223
struct ndb_query_results *results,
@@ -3367,11 +3446,11 @@ static enum ndb_query_plan ndb_filter_plan(struct ndb_filter *filter)
33673446
// this is rougly similar to the heuristic in strfry's dbscan
33683447
if (ids) {
33693448
return NDB_PLAN_IDS;
3370-
} else if (authors && authors->count <= 5) {
3371-
// TODO: actually implment author plan and use it
3372-
//return NDB_PLAN_AUTHORS;
3373-
return NDB_PLAN_CREATED;
3374-
} else if (tags && tags->count <= 5) {
3449+
} else if (kinds && authors && authors->count <= 10) {
3450+
return NDB_PLAN_AUTHOR_KINDS;
3451+
} else if (authors && authors->count <= 10) {
3452+
return NDB_PLAN_AUTHORS;
3453+
} else if (tags && tags->count <= 10) {
33753454
return NDB_PLAN_TAGS;
33763455
} else if (kinds) {
33773456
return NDB_PLAN_KINDS;
@@ -3434,8 +3513,17 @@ static int ndb_query_filter(struct ndb_txn *txn, struct ndb_filter *filter,
34343513
return 0;
34353514
break;
34363515
case NDB_PLAN_AUTHORS:
3437-
// TODO: finish authors query plan
3438-
return 0;
3516+
if (!ndb_query_plan_execute_authors(txn, filter, &results, limit))
3517+
return 0;
3518+
break;
3519+
case NDB_PLAN_AUTHOR_KINDS:
3520+
/* TODO: author kinds
3521+
if (!ndb_query_plan_execute_author_kinds(txn, filter, &results, limit))
3522+
return 0;
3523+
*/
3524+
if (!ndb_query_plan_execute_authors(txn, filter, &results, limit))
3525+
return 0;
3526+
break;
34393527
}
34403528

34413529
*results_out = cursor_count(&results.cur, sizeof(*res));

0 commit comments

Comments
 (0)