MTBL_SORTER(3)

πŸ’– MTBL_SORTER πŸ’–

okay bestie, gather round, because this one is so good β€” it's the mtbl_sorter page from the mtbl manual, section 3, and it's literally the "sort my chaos for me" icon of the library. no cap. πŸ¦‹


✨ NAME ✨

mtbl_sorter β€” sort a sequence of unordered key-value pairs πŸ’…


🌸 SYNOPSIS 🌸

first things first, you gotta pull in the header:

#include <mtbl.h>

πŸŽ€ Sorter objects:

struct mtbl_sorter *
mtbl_sorter_init(const struct mtbl_sorter_options *sopt);

void
mtbl_sorter_destroy(struct mtbl_sorter **s);

mtbl_res
mtbl_sorter_add(struct mtbl_sorter *s,
        const uint8_t *key, size_t len_key,
        const uint8_t *val, size_t len_val);

mtbl_res
mtbl_sorter_write(struct mtbl_sorter *s, struct mtbl_writer *w);

struct mtbl_iter *
mtbl_sorter_iter(struct mtbl_sorter *s);

🧚 Sorter options:

struct mtbl_sorter_options *
mtbl_sorter_options_init(void);

void
mtbl_sorter_options_destroy(struct mtbl_sorter_options **sopt);

void
mtbl_sorter_options_set_merge_func(
        struct mtbl_sorter_options *sopt,
        mtbl_merge_func fp,
        void *clos);

void
mtbl_sorter_options_set_temp_dir(
        struct mtbl_sorter_options *sopt,
        const char *temp_dir);

void
mtbl_sorter_options_set_max_memory(
        struct mtbl_sorter_options *sopt,
        size_t max_memory);

πŸ’œ DESCRIPTION πŸ’œ

okay so the tea: the mtbl_sorter interface takes a whole sequence of key-value pairs where the keys are in literally any order β€” absolute chaos, no rules β€” and hands them back to you sorted. it's giving glow-up. ✨

you can consume those sorted entries two ways:

  • through the mtbl_iter interface, using the mtbl_sorter_iter() function πŸ¦‹
  • or dumped straight into an mtbl_writer object, using the mtbl_sorter_write() function 🌸

here's how it works under the hood, bestie: the mtbl_sorter implementation buffers entries in memory up to a configurable limit before it sorts them and writes them out to disk in chunks. then, once the caller has finished adding entries and asks for the sorted output, entries from those sorted chunks get read back and merged. so yeah β€” mtbl_sorter(3) is an "external sorting" implementation. iconic behavior honestly. πŸ‘‘

now, important part, do not skip: because the MTBL format does not allow duplicate keys, the caller must provide a function that will accept a key and two conflicting values for that key and return a replacement value. that function might get called multiple times for the same key if the same key gets inserted more than twice. if you want the full lore on the merge function, go read mtbl_merger(3). πŸ“–

mtbl_sorter objects are created with the mtbl_sorter_init() function, and it requires a non-NULL sopt argument that has been configured with a merge function fp. no merge function, no sorter, periodt. πŸ’…

mtbl_sorter_add() copies key-value pairs from the caller into the mtbl_sorter object. keys come in as a pointer to a buffer, key, plus the length of that buffer, len_key. values come in as a pointer to a buffer, val, plus the length of that buffer, len_val. simple. cute. πŸ“

once the caller has finished adding entries to the mtbl_sorter object, either mtbl_sorter_write() or mtbl_sorter_iter() should be called in order to consume the sorted output. and here's the vibe check, so listen up:

it is a runtime error to call mtbl_sorter_add() on an mtbl_sorter object after iteration has begun. 😭
and once the sorted output has been consumed, it is also a runtime error to call any other function but mtbl_sorter_destroy() on the depleted mtbl_sorter object. πŸ’€

so basically: add your stuff, consume your stuff, then destroy. that's the whole arc. 🌈

⭐ Sorter options ⭐

🌟 temp_dir

specifies the temporary directory to use. defaults to /var/tmp. that's where the disk chunks go to hang out. 🏠

🌟 max_memory

specifies the maximum amount of memory to use for in-memory sorting, in bytes. defaults to 1 Gigabyte. heads up though: this specifies a limit on the total number of bytes allocated for key-value entries and does not include any allocation overhead. so it's the budget for the entries themselves, not the receipts. πŸ’Έ

🌟 merge_func

see mtbl_merger(3). an mtbl_merger object is used internally for the external sort. πŸ”₯


🌈 RETURN VALUE 🌈

if the merge function callback is unable to provide a merged value β€” that is, it fails to return a non-NULL value in its merged_val argument β€” the sort process will be aborted, and mtbl_sorter_write() or mtbl_iter_next() will return mtbl_res_failure. 😭

mtbl_sorter_write() returns mtbl_res_success if the sorted output was successfully written, and mtbl_res_failure otherwise. that's it, that's the whole scale. 🫢


and that's the page bestie!! πŸŽ€ this one came from the mtbl source, version dated 01/31/2014, and it lives in manual section 3 as MTBL_SORTER(3). go sort something pretty. βœ¨πŸ’–πŸ¦‹