Skip to content

Commit b893f77

Browse files
committed
Fixed #746.
Eliminated redundant zone allocation in unpacking process. ARRAY and MAP is construced on the zone. STR, BIN, and EXT refer to unpack buffer, and the buffer is reference counted via zone (finalizer). So zone is only needed if those types are appeared during unpacking process. I set zone to NULL by default. And the context has the pointer to pointer to the zone. If the context meets ARRAY, MAP, STR, BIN, or EXT, and zone (via pointer) is NULL, then allocate new zone. It is lazy zone allocation strategy.
1 parent 8792f42 commit b893f77

File tree

1 file changed

+43
-37
lines changed

1 file changed

+43
-37
lines changed

src/unpack.c

Lines changed: 43 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919

2020
typedef struct {
21-
msgpack_zone* z;
21+
msgpack_zone** z;
2222
bool referenced;
2323
} unpack_user;
2424

@@ -197,7 +197,13 @@ static inline int template_callback_array(unpack_user* u, unsigned int n, msgpac
197197
// integer overflow
198198
return MSGPACK_UNPACK_NOMEM_ERROR;
199199
}
200-
o->via.array.ptr = (msgpack_object*)msgpack_zone_malloc(u->z, size);
200+
if (*u->z == NULL) {
201+
*u->z = msgpack_zone_new(MSGPACK_ZONE_CHUNK_SIZE);
202+
if(*u->z == NULL) {
203+
return MSGPACK_UNPACK_NOMEM_ERROR;
204+
}
205+
}
206+
o->via.array.ptr = (msgpack_object*)msgpack_zone_malloc(*u->z, size);
201207
if(o->via.array.ptr == NULL) { return MSGPACK_UNPACK_NOMEM_ERROR; }
202208
return 0;
203209
}
@@ -224,7 +230,13 @@ static inline int template_callback_map(unpack_user* u, unsigned int n, msgpack_
224230
// integer overflow
225231
return MSGPACK_UNPACK_NOMEM_ERROR;
226232
}
227-
o->via.map.ptr = (msgpack_object_kv*)msgpack_zone_malloc(u->z, size);
233+
if (*u->z == NULL) {
234+
*u->z = msgpack_zone_new(MSGPACK_ZONE_CHUNK_SIZE);
235+
if(*u->z == NULL) {
236+
return MSGPACK_UNPACK_NOMEM_ERROR;
237+
}
238+
}
239+
o->via.map.ptr = (msgpack_object_kv*)msgpack_zone_malloc(*u->z, size);
228240
if(o->via.map.ptr == NULL) { return MSGPACK_UNPACK_NOMEM_ERROR; }
229241
return 0;
230242
}
@@ -245,8 +257,13 @@ static inline int template_callback_map_item(unpack_user* u, msgpack_object* c,
245257

246258
static inline int template_callback_str(unpack_user* u, const char* b, const char* p, unsigned int l, msgpack_object* o)
247259
{
248-
MSGPACK_UNUSED(u);
249260
MSGPACK_UNUSED(b);
261+
if (*u->z == NULL) {
262+
*u->z = msgpack_zone_new(MSGPACK_ZONE_CHUNK_SIZE);
263+
if(*u->z == NULL) {
264+
return MSGPACK_UNPACK_NOMEM_ERROR;
265+
}
266+
}
250267
o->type = MSGPACK_OBJECT_STR;
251268
o->via.str.ptr = p;
252269
o->via.str.size = l;
@@ -256,8 +273,13 @@ static inline int template_callback_str(unpack_user* u, const char* b, const cha
256273

257274
static inline int template_callback_bin(unpack_user* u, const char* b, const char* p, unsigned int l, msgpack_object* o)
258275
{
259-
MSGPACK_UNUSED(u);
260276
MSGPACK_UNUSED(b);
277+
if (*u->z == NULL) {
278+
*u->z = msgpack_zone_new(MSGPACK_ZONE_CHUNK_SIZE);
279+
if(*u->z == NULL) {
280+
return MSGPACK_UNPACK_NOMEM_ERROR;
281+
}
282+
}
261283
o->type = MSGPACK_OBJECT_BIN;
262284
o->via.bin.ptr = p;
263285
o->via.bin.size = l;
@@ -267,11 +289,16 @@ static inline int template_callback_bin(unpack_user* u, const char* b, const cha
267289

268290
static inline int template_callback_ext(unpack_user* u, const char* b, const char* p, unsigned int l, msgpack_object* o)
269291
{
292+
MSGPACK_UNUSED(b);
270293
if (l == 0) {
271294
return MSGPACK_UNPACK_PARSE_ERROR;
272295
}
273-
MSGPACK_UNUSED(u);
274-
MSGPACK_UNUSED(b);
296+
if (*u->z == NULL) {
297+
*u->z = msgpack_zone_new(MSGPACK_ZONE_CHUNK_SIZE);
298+
if(*u->z == NULL) {
299+
return MSGPACK_UNPACK_NOMEM_ERROR;
300+
}
301+
}
275302
o->type = MSGPACK_OBJECT_EXT;
276303
o->via.ext.type = *p;
277304
o->via.ext.ptr = p + 1;
@@ -317,7 +344,6 @@ bool msgpack_unpacker_init(msgpack_unpacker* mpac, size_t initial_buffer_size)
317344
{
318345
char* buffer;
319346
void* ctx;
320-
msgpack_zone* z;
321347

322348
if(initial_buffer_size < COUNTER_SIZE) {
323349
initial_buffer_size = COUNTER_SIZE;
@@ -334,26 +360,19 @@ bool msgpack_unpacker_init(msgpack_unpacker* mpac, size_t initial_buffer_size)
334360
return false;
335361
}
336362

337-
z = msgpack_zone_new(MSGPACK_ZONE_CHUNK_SIZE);
338-
if(z == NULL) {
339-
free(ctx);
340-
free(buffer);
341-
return false;
342-
}
343-
344363
mpac->buffer = buffer;
345364
mpac->used = COUNTER_SIZE;
346365
mpac->free = initial_buffer_size - mpac->used;
347366
mpac->off = COUNTER_SIZE;
348367
mpac->parsed = 0;
349368
mpac->initial_buffer_size = initial_buffer_size;
350-
mpac->z = z;
369+
mpac->z = NULL;
351370
mpac->ctx = ctx;
352371

353372
init_count(mpac->buffer);
354373

355374
template_init(CTX_CAST(mpac->ctx));
356-
CTX_CAST(mpac->ctx)->user.z = mpac->z;
375+
CTX_CAST(mpac->ctx)->user.z = &mpac->z;
357376
CTX_CAST(mpac->ctx)->user.referenced = false;
358377

359378
return true;
@@ -480,21 +499,15 @@ msgpack_object msgpack_unpacker_data(msgpack_unpacker* mpac)
480499

481500
msgpack_zone* msgpack_unpacker_release_zone(msgpack_unpacker* mpac)
482501
{
483-
msgpack_zone* r;
484-
msgpack_zone* old;
502+
msgpack_zone* old = mpac->z;
485503

504+
if (old == NULL) return NULL;
486505
if(!msgpack_unpacker_flush_zone(mpac)) {
487506
return NULL;
488507
}
489508

490-
r = msgpack_zone_new(MSGPACK_ZONE_CHUNK_SIZE);
491-
if(r == NULL) {
492-
return NULL;
493-
}
494-
495-
old = mpac->z;
496-
mpac->z = r;
497-
CTX_CAST(mpac->ctx)->user.z = mpac->z;
509+
mpac->z = NULL;
510+
CTX_CAST(mpac->ctx)->user.z = &mpac->z;
498511

499512
return old;
500513
}
@@ -596,7 +609,7 @@ msgpack_unpack(const char* data, size_t len, size_t* off,
596609
template_context ctx;
597610
template_init(&ctx);
598611

599-
ctx.user.z = result_zone;
612+
ctx.user.z = &result_zone;
600613
ctx.user.referenced = false;
601614

602615
e = template_execute(&ctx, data, len, &noff);
@@ -633,19 +646,12 @@ msgpack_unpack_next(msgpack_unpacked* result,
633646
return MSGPACK_UNPACK_CONTINUE;
634647
}
635648

636-
if (!result->zone) {
637-
result->zone = msgpack_zone_new(MSGPACK_ZONE_CHUNK_SIZE);
638-
}
639-
640-
if (!result->zone) {
641-
return MSGPACK_UNPACK_NOMEM_ERROR;
642-
}
643-
else {
649+
{
644650
int e;
645651
template_context ctx;
646652
template_init(&ctx);
647653

648-
ctx.user.z = result->zone;
654+
ctx.user.z = &result->zone;
649655
ctx.user.referenced = false;
650656

651657
e = template_execute(&ctx, data, len, &noff);

0 commit comments

Comments
 (0)