Skip to content

Commit ad769dd

Browse files
committed
mp: new helper functions for map headers size
Signed-off-by: Eduardo Silva <eduardo@treasure-data.com>
1 parent 82a9d19 commit ad769dd

File tree

2 files changed

+98
-0
lines changed

2 files changed

+98
-0
lines changed

include/fluent-bit/flb_mp.h

+16
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,23 @@
2121
#ifndef FLB_MP_H
2222
#define FLB_MP_H
2323

24+
#include <msgpack.h>
25+
2426
int flb_mp_count(const void *data, size_t bytes);
2527
void flb_mp_set_map_header_size(char *buf, int arr_size);
2628

29+
30+
/*
31+
* Map header handling functions
32+
*/
33+
struct flb_mp_map_header {
34+
off_t offset;
35+
size_t entries;
36+
void *data;
37+
};
38+
39+
int flb_mp_map_header_init(struct flb_mp_map_header *mh, msgpack_packer *mp_pck);
40+
int flb_mp_map_header_append(struct flb_mp_map_header *mh);
41+
void flb_mp_map_header_end(struct flb_mp_map_header *mh);
42+
2743
#endif

src/flb_mp.c

+82
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@
1919
*/
2020

2121
#include <fluent-bit/flb_info.h>
22+
#include <fluent-bit/flb_utils.h>
23+
#include <fluent-bit/flb_mp.h>
24+
2225
#include <msgpack.h>
2326
#include <mpack/mpack.h>
2427

@@ -60,3 +63,82 @@ void flb_mp_set_map_header_size(char *buf, int arr_size)
6063
pack_uint32(tmp, arr_size);
6164
}
6265
}
66+
67+
/*
68+
* msgpack-c requires to set the number of the entries in a map beforehand. For our
69+
* use case this adds some complexity, having developers to count all possible
70+
* entries that might be added.
71+
*
72+
* As a workaround and to avoid map's recomposition over and over, this simple API
73+
* allows to initialize the array header, 'register' new entries (as counters) and
74+
* finalize, upon finalization the proper array header size is adjusted.
75+
*
76+
* To make things easier, we make sure msgpack-c always register an array type of
77+
* 32 bits (identified by 0xdf, for number of entries >= 65536). Yes, for every
78+
* array using this API it will use 2 more bytes, not a big ideal. So whoever
79+
* uses this API, use it only if you don't know the exact number of entries to add.
80+
*
81+
* MANDATORY: make sure to always initialize, register every entry and finalize,
82+
* otherwise you will get a corrupted or incomplete msgpack buffer.
83+
*
84+
* Usage example
85+
* =============
86+
*
87+
* struct flb_mp_map_head mh;
88+
*
89+
* flb_mp_map_header_init(&mh, mp_pck);
90+
*
91+
* -- First key/value entry --
92+
* flb_mp_map_header_append(&mh);
93+
* msgpack_pack_str(mp_pck, 4);
94+
* msgpack_pack_str_body(mp_pck, "cool", 4);
95+
* msgpack_pack_true(mp_pck);
96+
*
97+
* -- Second key/value entry --
98+
* flb_mp_map_header_append(&mh);
99+
* msgpack_pack_str(mp_pck, 4);
100+
* msgpack_pack_str_body(mp_pck, "slow", 4);
101+
* msgpack_pack_false(mp_pck);
102+
*
103+
* -- Finalize Map --
104+
* flb_mp_map_header_end(&mh);
105+
*/
106+
int flb_mp_map_header_init(struct flb_mp_map_header *mh, msgpack_packer *mp_pck)
107+
{
108+
msgpack_sbuffer *mp_sbuf;
109+
110+
mp_sbuf = (msgpack_sbuffer *) mp_pck->data;
111+
112+
/* map sbuffer */
113+
mh->data = mp_pck->data;
114+
115+
/* Reset entries */
116+
mh->entries = 0;
117+
118+
/* Store the next byte available */
119+
mh->offset = mp_sbuf->size;
120+
121+
/*
122+
* Pack a map with size = 65536, so we force the underlaying msgpack-c
123+
* to use a 32 bit buffer size (0xdf), reference:
124+
*
125+
* - https://github.com/msgpack/msgpack/blob/master/spec.md#map-format-family
126+
*/
127+
return msgpack_pack_map(mp_pck, 65536);
128+
}
129+
130+
int flb_mp_map_header_append(struct flb_mp_map_header *mh)
131+
{
132+
mh->entries++;
133+
return mh->entries;
134+
}
135+
136+
void flb_mp_map_header_end(struct flb_mp_map_header *mh)
137+
{
138+
char *ptr;
139+
msgpack_sbuffer *mp_sbuf;
140+
141+
mp_sbuf = mh->data;
142+
ptr = (char *) mp_sbuf->data + mh->offset;
143+
flb_mp_set_map_header_size(ptr, mh->entries);
144+
}

0 commit comments

Comments
 (0)