Skip to content

Commit

Permalink
mp: new helper functions for map headers size
Browse files Browse the repository at this point in the history
Signed-off-by: Eduardo Silva <[email protected]>
  • Loading branch information
edsiper committed Jul 22, 2020
1 parent 82a9d19 commit ad769dd
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 0 deletions.
16 changes: 16 additions & 0 deletions include/fluent-bit/flb_mp.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,23 @@
#ifndef FLB_MP_H
#define FLB_MP_H

#include <msgpack.h>

int flb_mp_count(const void *data, size_t bytes);
void flb_mp_set_map_header_size(char *buf, int arr_size);


/*
* Map header handling functions
*/
struct flb_mp_map_header {
off_t offset;
size_t entries;
void *data;
};

int flb_mp_map_header_init(struct flb_mp_map_header *mh, msgpack_packer *mp_pck);
int flb_mp_map_header_append(struct flb_mp_map_header *mh);
void flb_mp_map_header_end(struct flb_mp_map_header *mh);

#endif
82 changes: 82 additions & 0 deletions src/flb_mp.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
*/

#include <fluent-bit/flb_info.h>
#include <fluent-bit/flb_utils.h>
#include <fluent-bit/flb_mp.h>

#include <msgpack.h>
#include <mpack/mpack.h>

Expand Down Expand Up @@ -60,3 +63,82 @@ void flb_mp_set_map_header_size(char *buf, int arr_size)
pack_uint32(tmp, arr_size);
}
}

/*
* msgpack-c requires to set the number of the entries in a map beforehand. For our
* use case this adds some complexity, having developers to count all possible
* entries that might be added.
*
* As a workaround and to avoid map's recomposition over and over, this simple API
* allows to initialize the array header, 'register' new entries (as counters) and
* finalize, upon finalization the proper array header size is adjusted.
*
* To make things easier, we make sure msgpack-c always register an array type of
* 32 bits (identified by 0xdf, for number of entries >= 65536). Yes, for every
* array using this API it will use 2 more bytes, not a big ideal. So whoever
* uses this API, use it only if you don't know the exact number of entries to add.
*
* MANDATORY: make sure to always initialize, register every entry and finalize,
* otherwise you will get a corrupted or incomplete msgpack buffer.
*
* Usage example
* =============
*
* struct flb_mp_map_head mh;
*
* flb_mp_map_header_init(&mh, mp_pck);
*
* -- First key/value entry --
* flb_mp_map_header_append(&mh);
* msgpack_pack_str(mp_pck, 4);
* msgpack_pack_str_body(mp_pck, "cool", 4);
* msgpack_pack_true(mp_pck);
*
* -- Second key/value entry --
* flb_mp_map_header_append(&mh);
* msgpack_pack_str(mp_pck, 4);
* msgpack_pack_str_body(mp_pck, "slow", 4);
* msgpack_pack_false(mp_pck);
*
* -- Finalize Map --
* flb_mp_map_header_end(&mh);
*/
int flb_mp_map_header_init(struct flb_mp_map_header *mh, msgpack_packer *mp_pck)
{
msgpack_sbuffer *mp_sbuf;

mp_sbuf = (msgpack_sbuffer *) mp_pck->data;

/* map sbuffer */
mh->data = mp_pck->data;

/* Reset entries */
mh->entries = 0;

/* Store the next byte available */
mh->offset = mp_sbuf->size;

/*
* Pack a map with size = 65536, so we force the underlaying msgpack-c
* to use a 32 bit buffer size (0xdf), reference:
*
* - https://github.com/msgpack/msgpack/blob/master/spec.md#map-format-family
*/
return msgpack_pack_map(mp_pck, 65536);
}

int flb_mp_map_header_append(struct flb_mp_map_header *mh)
{
mh->entries++;
return mh->entries;
}

void flb_mp_map_header_end(struct flb_mp_map_header *mh)
{
char *ptr;
msgpack_sbuffer *mp_sbuf;

mp_sbuf = mh->data;
ptr = (char *) mp_sbuf->data + mh->offset;
flb_mp_set_map_header_size(ptr, mh->entries);
}

0 comments on commit ad769dd

Please sign in to comment.