@@ -3139,6 +3139,85 @@ static int ndb_encode_tag_key(unsigned char *buf, int buf_size,
3139
3139
return writer .p - writer .start ;
3140
3140
}
3141
3141
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
+
3142
3221
static int ndb_query_plan_execute_created_at (struct ndb_txn * txn ,
3143
3222
struct ndb_filter * filter ,
3144
3223
struct ndb_query_results * results ,
@@ -3367,11 +3446,11 @@ static enum ndb_query_plan ndb_filter_plan(struct ndb_filter *filter)
3367
3446
// this is rougly similar to the heuristic in strfry's dbscan
3368
3447
if (ids ) {
3369
3448
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 ) {
3375
3454
return NDB_PLAN_TAGS ;
3376
3455
} else if (kinds ) {
3377
3456
return NDB_PLAN_KINDS ;
@@ -3434,8 +3513,17 @@ static int ndb_query_filter(struct ndb_txn *txn, struct ndb_filter *filter,
3434
3513
return 0 ;
3435
3514
break ;
3436
3515
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 ;
3439
3527
}
3440
3528
3441
3529
* results_out = cursor_count (& results .cur , sizeof (* res ));
0 commit comments