nostrdb

an unfairly fast embedded nostr database backed by lmdb
git clone git://jb55.com/nostrdb
Log | Files | Refs | README | LICENSE

commit 93cfa17bd6d24aa3326ba000ed62bc5c0a9e3cd0
parent bd7487d34d684d776cb051baa36ca9ad92b6b193
Author: William Casarin <jb55@jb55.com>
Date:   Sat, 22 Jul 2023 15:23:39 -0700

add content length to ndb_note

We don't need this for every string, but it's nice to have for content
so you don't have to strlen it if its very large.

Diffstat:
Mnostrdb.c | 17++++++++++++++---
Mnostrdb.h | 7+++++++
Mtest.c | 7++++++-
3 files changed, 27 insertions(+), 4 deletions(-)

diff --git a/nostrdb.c b/nostrdb.c @@ -207,6 +207,7 @@ int ndb_builder_make_str(struct ndb_builder *builder, const char *str, int len, int ndb_builder_set_content(struct ndb_builder *builder, const char *content, int len) { + builder->note->content_length = len; return ndb_builder_make_str(builder, content, len, &builder->note->content); } @@ -238,12 +239,14 @@ static int ndb_builder_finalize_tag(struct ndb_builder *builder, /// Unescape and push json strings static int ndb_builder_make_json_str(struct ndb_builder *builder, const char *str, int len, - union packed_str *pstr) + union packed_str *pstr, + int *written) { // let's not care about de-duping these. we should just unescape // in-place directly into the strings table. const char *p, *end, *start; + unsigned char *builder_start; // always try compact strings first if (ndb_builder_try_compact_str(builder, str, len, pstr)) @@ -253,6 +256,7 @@ static int ndb_builder_make_json_str(struct ndb_builder *builder, start = str; // Initialize start to the beginning of the string *pstr = ndb_offset_str(builder->strings.p - builder->strings.start); + builder_start = builder->strings.p; for (p = str; p < end; p++) { if (*p == '\\' && p+1 < end) { @@ -313,6 +317,9 @@ static int ndb_builder_make_json_str(struct ndb_builder *builder, return 0; } + if (written) + *written = builder->strings.p - builder_start; + // TODO: dedupe these!? return cursor_push_byte(&builder->strings, '\0'); } @@ -321,7 +328,7 @@ static int ndb_builder_push_json_tag(struct ndb_builder *builder, const char *str, int len) { union packed_str pstr; - if (!ndb_builder_make_json_str(builder, str, len, &pstr)) + if (!ndb_builder_make_json_str(builder, str, len, &pstr, NULL)) return 0; return ndb_builder_finalize_tag(builder, pstr); } @@ -468,11 +475,15 @@ int ndb_note_from_json(const char *json, int len, struct ndb_note **note, // content tok = &parser.toks[i+1]; union packed_str pstr; + tok_len = toksize(tok); + int written; if (!ndb_builder_make_json_str(&parser.builder, json + tok->start, - toksize(tok), &pstr)) { + tok_len, &pstr, + &written)) { return 0; } + parser.builder.note->content_length = written; parser.builder.note->content = pstr; } } else if (start[0] == 't' && jsoneq(json, tok, tok_len, "tags")) { diff --git a/nostrdb.h b/nostrdb.h @@ -40,6 +40,7 @@ struct ndb_note { uint32_t created_at; uint32_t kind; + uint32_t content_length; union packed_str content; uint32_t strings; uint32_t json; @@ -84,6 +85,7 @@ static inline int ndb_str_is_packed(union packed_str str) return (str.offset >> 31) & 0x1; } + static inline const char * ndb_note_str(struct ndb_note *note, union packed_str *str) { @@ -146,6 +148,11 @@ static inline const char * ndb_note_content(struct ndb_note *note) return ndb_note_str(note, &note->content); } +static inline uint32_t ndb_note_content_length(struct ndb_note *note) +{ + return note->content_length; +} + static inline struct ndb_note * ndb_note_from_bytes(unsigned char *bytes) { struct ndb_note *note = (struct ndb_note *)bytes; diff --git a/test.c b/test.c @@ -108,7 +108,7 @@ static void test_parse_contact_list() size = ndb_note_from_json((const char*)json, written, &note, buf, alloc_size); printf("ndb_note_from_json size %d\n", size); assert(size > 0); - assert(size == 59058); + assert(size == 59062); const char* expected_content = "{\"wss://nos.lol\":{\"write\":true,\"read\":true}," @@ -123,6 +123,11 @@ static void test_parse_contact_list() assert(!strcmp(expected_content, ndb_note_content(note))); assert(ndb_note_created_at(note) == 1689904312); assert(ndb_note_kind(note) == 3); + //printf("note content length %d\n", ndb_note_content_length(note)); + printf("ndb_content_len %d, expected_len %ld\n", + ndb_note_content_length(note), + strlen(expected_content)); + assert(ndb_note_content_length(note) == strlen(expected_content)); write_file("test_contacts_ndb_note", (unsigned char *)note, size); printf("wrote test_contacts_ndb_note (raw ndb_note)\n");