Skip to content

Commit e5b9a9f

Browse files
committed
migration: implement ndb_count_reactions
also verify it matches the online counting
1 parent 4fa1b02 commit e5b9a9f

File tree

2 files changed

+95
-30
lines changed

2 files changed

+95
-30
lines changed

src/nostrdb.c

Lines changed: 83 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2002,14 +2002,94 @@ static int ndb_rebuild_note_indices(struct ndb_txn *txn, enum ndb_dbs *indices,
20022002

20032003
int ndb_cursor_start(MDB_cursor *cur, MDB_val *k, MDB_val *v);
20042004

2005+
// find the last id tag in a note (e, p, etc)
2006+
static unsigned char *ndb_note_last_id_tag(struct ndb_note *note, char type)
2007+
{
2008+
unsigned char *last = NULL;
2009+
struct ndb_iterator iter;
2010+
struct ndb_str str;
2011+
2012+
// get the liked event id (last id)
2013+
ndb_tags_iterate_start(note, &iter);
2014+
2015+
while (ndb_tags_iterate_next(&iter)) {
2016+
if (iter.tag->count < 2)
2017+
continue;
2018+
2019+
str = ndb_tag_str(note, iter.tag, 0);
2020+
2021+
// assign liked to the last e tag
2022+
if (str.flag == NDB_PACKED_STR && str.str[0] == type) {
2023+
str = ndb_tag_str(note, iter.tag, 1);
2024+
if (str.flag == NDB_PACKED_ID)
2025+
last = str.id;
2026+
}
2027+
}
2028+
2029+
return last;
2030+
}
2031+
2032+
20052033
static int ndb_count_replies(struct ndb_txn *txn, const unsigned char *note_id, uint16_t *direct_replies, uint32_t *thread_replies)
20062034
{
20072035
return 1;
20082036
}
20092037

20102038
/* count all of the reactions for a note */
2011-
static int ndb_count_reactions(struct ndb_txn *txn, const unsigned char *note_id, uint32_t *count)
2039+
int ndb_count_reactions(struct ndb_txn *txn, const unsigned char *note_id, uint32_t *count)
20122040
{
2041+
MDB_val k, v;
2042+
MDB_cursor *cur;
2043+
MDB_dbi db;
2044+
2045+
int rc;
2046+
uint64_t note_key;
2047+
size_t size;
2048+
struct ndb_note *note;
2049+
unsigned char *keybuf, *last_id;
2050+
char buffer[41]; /* 1 + 32 + 8 */
2051+
*count = 0;
2052+
2053+
db = txn->lmdb->dbs[NDB_DB_NOTE_TAGS];
2054+
if ((rc = mdb_cursor_open(txn->mdb_txn, db, &cur))) {
2055+
fprintf(stderr, "ndb_count_reactions: mdb_cursor_open failed, error %d\n", rc);
2056+
return 0;
2057+
}
2058+
2059+
buffer[0] = 'e';
2060+
memcpy(&buffer[1], note_id, 32);
2061+
memset(&buffer[33], 0x00, 8);
2062+
2063+
k.mv_data = buffer;
2064+
k.mv_size = sizeof(buffer);
2065+
v.mv_data = NULL;
2066+
v.mv_size = 0;
2067+
2068+
if (mdb_cursor_get(cur, &k, &v, MDB_SET_RANGE))
2069+
goto cleanup;
2070+
2071+
do {
2072+
keybuf = (unsigned char *)k.mv_data;
2073+
note_key = *((uint64_t*)v.mv_data);
2074+
if (k.mv_size < sizeof(buffer))
2075+
break;
2076+
if (keybuf[0] != 'e')
2077+
break;
2078+
if (memcmp(&keybuf[1], note_id, 32))
2079+
break;
2080+
if (!(note = ndb_get_note_by_key(txn, note_key, &size)))
2081+
continue;
2082+
if (ndb_note_kind(note) != 7)
2083+
continue;
2084+
if (!(last_id = ndb_note_last_id_tag(note, 'e')))
2085+
continue;
2086+
if (memcmp(last_id, note_id, 32))
2087+
continue;
2088+
(*count)++;
2089+
} while (mdb_cursor_get(cur, &k, &v, MDB_NEXT) == 0);
2090+
2091+
cleanup:
2092+
mdb_cursor_close(cur);
20132093
return 1;
20142094
}
20152095

@@ -2108,7 +2188,7 @@ static void ndb_note_meta_builder_count_reactions(struct ndb_txn *txn, struct nd
21082188
//
21092189

21102190
/* switch from flatbuffer stats to custom v2 */
2111-
static int ndb_migrate_reaction_stats(struct ndb_txn *txn)
2191+
static int ndb_migrate_metadata(struct ndb_txn *txn)
21122192
{
21132193
MDB_val k, k2, v, v2;
21142194
MDB_cursor *cur;
@@ -2491,7 +2571,7 @@ static struct ndb_migration MIGRATIONS[] = {
24912571
{ .fn = ndb_migrate_lower_user_search_indices },
24922572
{ .fn = ndb_migrate_utf8_profile_names },
24932573
{ .fn = ndb_migrate_profile_indices },
2494-
//{ .fn = ndb_migrate_reaction_stats },
2574+
//{ .fn = ndb_migrate_metadata },
24952575
};
24962576

24972577

@@ -3477,33 +3557,6 @@ static int ndb_write_profile(struct ndb_txn *txn,
34773557
return 1;
34783558
}
34793559

3480-
// find the last id tag in a note (e, p, etc)
3481-
static unsigned char *ndb_note_last_id_tag(struct ndb_note *note, char type)
3482-
{
3483-
unsigned char *last = NULL;
3484-
struct ndb_iterator iter;
3485-
struct ndb_str str;
3486-
3487-
// get the liked event id (last id)
3488-
ndb_tags_iterate_start(note, &iter);
3489-
3490-
while (ndb_tags_iterate_next(&iter)) {
3491-
if (iter.tag->count < 2)
3492-
continue;
3493-
3494-
str = ndb_tag_str(note, iter.tag, 0);
3495-
3496-
// assign liked to the last e tag
3497-
if (str.flag == NDB_PACKED_STR && str.str[0] == type) {
3498-
str = ndb_tag_str(note, iter.tag, 1);
3499-
if (str.flag == NDB_PACKED_ID)
3500-
last = str.id;
3501-
}
3502-
}
3503-
3504-
return last;
3505-
}
3506-
35073560
int ndb_set_note_meta(struct ndb *ndb, const unsigned char *id, struct ndb_note_meta *meta)
35083561
{
35093562
struct ndb_writer_msg msg;

test.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ static void delete_test_db() {
3030
unlink(TEST_DIR "/data.lock");
3131
}
3232

33+
int ndb_count_reactions(struct ndb_txn *txn, const unsigned char *note_id, uint32_t *count);
34+
3335
static void db_load_events(struct ndb *ndb, const char *filename)
3436
{
3537
size_t filesize;
@@ -132,7 +134,17 @@ static void test_count_metadata()
132134
assert(reactions > 0);
133135
assert(total_reactions == reactions);
134136

137+
138+
ndb_end_query(&txn);
139+
140+
ndb_begin_query(ndb, &txn);
141+
/* this is used in the migration code,
142+
* let's make sure it matches the online logic */
143+
ndb_count_reactions(&txn, id, &reactions);
144+
printf("\t# after-counted reactions %d\n", reactions);
145+
assert(reactions == total_reactions);
135146
ndb_end_query(&txn);
147+
136148
ndb_destroy(ndb);
137149
delete_test_db();
138150

0 commit comments

Comments
 (0)