nostrdb

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

commit d21643aa2f7be3323cdddfdf72f6da12f1d5323e
parent b975cff7ba36400b33ef89efd4fb9e2bef5ebdc3
Author: William Casarin <jb55@jb55.com>
Date:   Sat, 30 Dec 2023 19:19:15 -0800

blocks: expose block iterator internals

so we don't need heap allocation. we will be calling this a lot in tight
render loops, we don't want to be allocating on each frame.

Diffstat:
Msrc/block.c | 36+++++++++++-------------------------
Msrc/block.h | 20--------------------
Msrc/invoice.c | 1+
Msrc/invoice.h | 10+---------
Msrc/nostrdb.h | 39+++++++++++++++++++++++++++++++++++++--
Mtest.c | 10++++++----
6 files changed, 56 insertions(+), 60 deletions(-)

diff --git a/src/block.c b/src/block.c @@ -4,13 +4,6 @@ #include "block.h" #include <stdlib.h> -struct ndb_block_iterator { - const char *content; - struct ndb_blocks *blocks; - struct ndb_block block; - struct cursor cur; -}; - int push_str_block(struct cursor *buf, const char *content, struct ndb_str_block *block) { return cursor_push_varint(buf, block->str - content) && cursor_push_varint(buf, block->len); @@ -133,32 +126,25 @@ enum ndb_block_type ndb_get_block_type(struct ndb_block *block) { } // BLOCK ITERATORS -struct ndb_block_iterator *ndb_blocks_iterate_start(const char *content, struct ndb_blocks *blocks) { - struct ndb_block_iterator *iter = malloc(sizeof(*iter)); - if (!iter) - return NULL; - +void ndb_blocks_iterate_start(const char *content, struct ndb_blocks *blocks, struct ndb_block_iterator *iter) { iter->blocks = blocks; iter->content = content; - - make_cursor((unsigned char *)blocks->blocks, - blocks->blocks + blocks->blocks_size, &iter->cur); - - return iter; -} - -void ndb_blocks_iterate_free(struct ndb_block_iterator *iter) -{ - if (iter) - free(iter); + iter->p = blocks->blocks; } struct ndb_block *ndb_blocks_iterate_next(struct ndb_block_iterator *iter) { - while (iter->cur.p < iter->cur.end) { - if (!pull_block(iter->content, &iter->cur, &iter->block)) { + struct cursor cur; + cur.start = iter->blocks->blocks; + cur.p = iter->p; + cur.end = iter->blocks->blocks + iter->blocks->blocks_size; + + while (cur.p < cur.end) { + if (!pull_block(iter->content, &cur, &iter->block)) { + iter->p = cur.p; return NULL; } else { + iter->p = cur.p; return &iter->block; } } diff --git a/src/block.h b/src/block.h @@ -29,26 +29,6 @@ struct ndb_blocks { #pragma pack(pop) -struct ndb_mention_bech32_block { - struct ndb_str_block str; - struct nostr_bech32 bech32; -}; - -struct ndb_invoice_block { - struct ndb_str_block invstr; - struct ndb_invoice invoice; -}; - -struct ndb_block { - enum ndb_block_type type; - union { - struct ndb_str_block str; - struct ndb_invoice_block invoice; - struct ndb_mention_bech32_block mention_bech32; - uint32_t mention_index; - } block; -}; - int push_str_block(struct cursor *buf, const char *content, struct ndb_str_block *block); int pull_str_block(struct cursor *buf, const char *content, struct ndb_str_block *block); diff --git a/src/invoice.c b/src/invoice.c @@ -1,6 +1,7 @@ #include "cursor.h" #include "invoice.h" +#include "nostrdb.h" #include "bolt11/bolt11.h" #include "bolt11/amount.h" diff --git a/src/invoice.h b/src/invoice.h @@ -4,18 +4,10 @@ #include <inttypes.h> #include "cursor.h" +#include "nostrdb.h" struct bolt11; -struct ndb_invoice { - unsigned char version; - uint64_t amount; - uint64_t timestamp; - uint64_t expiry; - char *description; - unsigned char *description_hash; -}; - // ENCODING int ndb_encode_invoice(struct cursor *cur, struct bolt11 *invoice); int ndb_decode_invoice(struct cursor *cur, struct ndb_invoice *invoice); diff --git a/src/nostrdb.h b/src/nostrdb.h @@ -360,6 +360,42 @@ struct nostr_bech32 { }; +struct ndb_mention_bech32_block { + struct ndb_str_block str; + struct nostr_bech32 bech32; +}; + +struct ndb_invoice { + unsigned char version; + uint64_t amount; + uint64_t timestamp; + uint64_t expiry; + char *description; + unsigned char *description_hash; +}; + +struct ndb_invoice_block { + struct ndb_str_block invstr; + struct ndb_invoice invoice; +}; + +struct ndb_block { + enum ndb_block_type type; + union { + struct ndb_str_block str; + struct ndb_invoice_block invoice; + struct ndb_mention_bech32_block mention_bech32; + uint32_t mention_index; + } block; +}; + +struct ndb_block_iterator { + const char *content; + struct ndb_blocks *blocks; + struct ndb_block block; + unsigned char *p; +}; + // CONFIG void ndb_default_config(struct ndb_config *); void ndb_config_set_ingest_threads(struct ndb_config *config, int threads); @@ -479,8 +515,7 @@ void ndb_blocks_free(struct ndb_blocks *blocks); struct ndb_blocks *ndb_get_blocks_by_key(struct ndb *ndb, struct ndb_txn *txn, uint64_t note_key); // BLOCK ITERATORS -struct ndb_block_iterator *ndb_blocks_iterate_start(const char *, struct ndb_blocks *); -void ndb_blocks_iterate_free(struct ndb_block_iterator *); +void ndb_blocks_iterate_start(const char *, struct ndb_blocks *, struct ndb_block_iterator *); struct ndb_block *ndb_blocks_iterate_next(struct ndb_block_iterator *); // STR BLOCKS diff --git a/test.c b/test.c @@ -782,6 +782,8 @@ static void test_parse_nevent() { struct ndb_blocks *blocks; struct ndb_block *block = NULL; struct nostr_bech32 *bech32; + struct ndb_block_iterator iterator, *iter; + iter = &iterator; int ok = 0; static unsigned char event_id[] = { 0x50, 0x5f, 0x0f, 0x0c, 0x98, 0x1d, 0x4b, 0xea, 0x76, 0x82, 0x1b, 0x53, @@ -789,7 +791,7 @@ static void test_parse_nevent() { 0x7c, 0x88, 0x9d, 0xd7, 0x91, 0x1e, 0x6a, 0x74 }; assert(ndb_parse_content(buf, sizeof(buf), content, strlen(content), &blocks)); - struct ndb_block_iterator *iter = ndb_blocks_iterate_start(content, blocks); + ndb_blocks_iterate_start(content, blocks, iter); assert(blocks->num_blocks == 3); while ((block = ndb_blocks_iterate_next(iter))) { switch (++ok) { @@ -821,11 +823,13 @@ static void test_url_parsing() { struct ndb_blocks *blocks; struct ndb_block *block; struct ndb_str_block *str; + struct ndb_block_iterator iterator, *iter; + iter = &iterator; assert(ndb_parse_content(buf, sizeof(buf), content, strlen(content), &blocks)); assert(blocks->num_blocks == 5); - struct ndb_block_iterator *iter = ndb_blocks_iterate_start(content, blocks); + ndb_blocks_iterate_start(content, blocks, iter); int i = 0; while ((block = ndb_blocks_iterate_next(iter))) { str = ndb_block_str(block); @@ -839,8 +843,6 @@ static void test_url_parsing() { } assert(i == 5); - ndb_blocks_iterate_free(iter); - }