msgpack 1.5.2 → 1.5.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/ChangeLog +18 -0
- data/README.md +3 -1
- data/bench/bench.rb +78 -0
- data/ext/msgpack/buffer.c +9 -36
- data/ext/msgpack/buffer.h +9 -1
- data/ext/msgpack/buffer_class.c +6 -6
- data/ext/msgpack/compat.h +0 -99
- data/ext/msgpack/extconf.rb +9 -11
- data/ext/msgpack/packer.c +0 -24
- data/ext/msgpack/packer.h +1 -7
- data/ext/msgpack/packer_class.c +1 -1
- data/ext/msgpack/unpacker.c +56 -65
- data/ext/msgpack/unpacker.h +10 -6
- data/ext/msgpack/unpacker_class.c +2 -3
- data/lib/msgpack/version.rb +1 -1
- data/msgpack.gemspec +1 -0
- data/spec/factory_spec.rb +28 -0
- data/spec/spec_helper.rb +5 -1
- data/spec/unpacker_spec.rb +12 -0
- metadata +18 -13
- data/bench/pack.rb +0 -23
- data/bench/pack_log.rb +0 -33
- data/bench/pack_log_long.rb +0 -65
- data/bench/pack_symbols.rb +0 -28
- data/bench/run.sh +0 -14
- data/bench/run_long.sh +0 -35
- data/bench/run_symbols.sh +0 -26
- data/bench/unpack.rb +0 -21
- data/bench/unpack_log.rb +0 -34
- data/bench/unpack_log_long.rb +0 -67
data/ext/msgpack/unpacker.c
CHANGED
@@ -34,6 +34,13 @@ static ID s_call;
|
|
34
34
|
static msgpack_rmem_t s_stack_rmem;
|
35
35
|
#endif
|
36
36
|
|
37
|
+
#if !defined(HAVE_RB_HASH_NEW_CAPA)
|
38
|
+
static inline VALUE rb_hash_new_capa(long capa)
|
39
|
+
{
|
40
|
+
return rb_hash_new();
|
41
|
+
}
|
42
|
+
#endif
|
43
|
+
|
37
44
|
void msgpack_unpacker_static_init()
|
38
45
|
{
|
39
46
|
#ifdef UNPACKER_STACK_RMEM
|
@@ -53,13 +60,16 @@ void msgpack_unpacker_static_destroy()
|
|
53
60
|
#define HEAD_BYTE_REQUIRED 0xc1
|
54
61
|
|
55
62
|
static inline msgpack_unpacker_stack_t* _msgpack_unpacker_new_stack(void) {
|
63
|
+
msgpack_unpacker_stack_t *stack = ZALLOC(msgpack_unpacker_stack_t);
|
64
|
+
stack->capacity = MSGPACK_UNPACKER_STACK_CAPACITY;
|
56
65
|
#ifdef UNPACKER_STACK_RMEM
|
57
|
-
|
66
|
+
stack->data = msgpack_rmem_alloc(&s_stack_rmem);
|
58
67
|
/*memset(uk->stack, 0, MSGPACK_UNPACKER_STACK_CAPACITY);*/
|
59
68
|
#else
|
60
|
-
/*uk->stack = calloc(MSGPACK_UNPACKER_STACK_CAPACITY, sizeof(
|
61
|
-
|
69
|
+
/*uk->stack = calloc(MSGPACK_UNPACKER_STACK_CAPACITY, sizeof(msgpack_unpacker_stack_entry_t));*/
|
70
|
+
stack->data = xmalloc(MSGPACK_UNPACKER_STACK_CAPACITY * sizeof(msgpack_unpacker_stack_entry_t));
|
62
71
|
#endif
|
72
|
+
return stack;
|
63
73
|
}
|
64
74
|
|
65
75
|
msgpack_unpacker_t* _msgpack_unpacker_new(void)
|
@@ -74,17 +84,17 @@ msgpack_unpacker_t* _msgpack_unpacker_new(void)
|
|
74
84
|
uk->reading_raw = Qnil;
|
75
85
|
|
76
86
|
uk->stack = _msgpack_unpacker_new_stack();
|
77
|
-
uk->stack_capacity = MSGPACK_UNPACKER_STACK_CAPACITY;
|
78
87
|
|
79
88
|
return uk;
|
80
89
|
}
|
81
90
|
|
82
91
|
static inline void _msgpack_unpacker_free_stack(msgpack_unpacker_stack_t* stack) {
|
83
92
|
#ifdef UNPACKER_STACK_RMEM
|
84
|
-
msgpack_rmem_free(&s_stack_rmem, stack);
|
93
|
+
msgpack_rmem_free(&s_stack_rmem, stack->data);
|
85
94
|
#else
|
86
|
-
xfree(stack);
|
95
|
+
xfree(stack->data);
|
87
96
|
#endif
|
97
|
+
xfree(stack);
|
88
98
|
}
|
89
99
|
|
90
100
|
void _msgpack_unpacker_destroy(msgpack_unpacker_t* uk)
|
@@ -93,18 +103,24 @@ void _msgpack_unpacker_destroy(msgpack_unpacker_t* uk)
|
|
93
103
|
msgpack_buffer_destroy(UNPACKER_BUFFER_(uk));
|
94
104
|
}
|
95
105
|
|
106
|
+
void msgpack_unpacker_mark_stack(msgpack_unpacker_stack_t* stack)
|
107
|
+
{
|
108
|
+
while (stack) {
|
109
|
+
msgpack_unpacker_stack_entry_t* s = stack->data;
|
110
|
+
msgpack_unpacker_stack_entry_t* send = stack->data + stack->depth;
|
111
|
+
for(; s < send; s++) {
|
112
|
+
rb_gc_mark(s->object);
|
113
|
+
rb_gc_mark(s->key);
|
114
|
+
}
|
115
|
+
stack = stack->parent;
|
116
|
+
}
|
117
|
+
}
|
118
|
+
|
96
119
|
void msgpack_unpacker_mark(msgpack_unpacker_t* uk)
|
97
120
|
{
|
98
121
|
rb_gc_mark(uk->last_object);
|
99
122
|
rb_gc_mark(uk->reading_raw);
|
100
|
-
|
101
|
-
msgpack_unpacker_stack_t* s = uk->stack;
|
102
|
-
msgpack_unpacker_stack_t* send = uk->stack + uk->stack_depth;
|
103
|
-
for(; s < send; s++) {
|
104
|
-
rb_gc_mark(s->object);
|
105
|
-
rb_gc_mark(s->key);
|
106
|
-
}
|
107
|
-
|
123
|
+
msgpack_unpacker_mark_stack(uk->stack);
|
108
124
|
/* See MessagePack_Buffer_wrap */
|
109
125
|
/* msgpack_buffer_mark(UNPACKER_BUFFER_(uk)); */
|
110
126
|
rb_gc_mark(uk->buffer_ref);
|
@@ -116,9 +132,8 @@ void _msgpack_unpacker_reset(msgpack_unpacker_t* uk)
|
|
116
132
|
|
117
133
|
uk->head_byte = HEAD_BYTE_REQUIRED;
|
118
134
|
|
119
|
-
/*memset(uk->stack, 0, sizeof(msgpack_unpacker_t) * uk->
|
120
|
-
uk->
|
121
|
-
|
135
|
+
/*memset(uk->stack, 0, sizeof(msgpack_unpacker_t) * uk->stack->depth);*/
|
136
|
+
uk->stack->depth = 0;
|
122
137
|
uk->last_object = Qnil;
|
123
138
|
uk->reading_raw = Qnil;
|
124
139
|
uk->reading_raw_remaining = 0;
|
@@ -170,6 +185,9 @@ static inline int object_complete_symbol(msgpack_unpacker_t* uk, VALUE object)
|
|
170
185
|
static inline int object_complete_ext(msgpack_unpacker_t* uk, int ext_type, VALUE str)
|
171
186
|
{
|
172
187
|
if (uk->optimized_symbol_ext_type && ext_type == uk->symbol_ext_type) {
|
188
|
+
if (RB_UNLIKELY(NIL_P(str))) { // empty extension is returned as Qnil
|
189
|
+
return object_complete_symbol(uk, ID2SYM(rb_intern3("", 0, rb_utf8_encoding())));
|
190
|
+
}
|
173
191
|
return object_complete_symbol(uk, rb_str_intern(str));
|
174
192
|
}
|
175
193
|
|
@@ -191,37 +209,37 @@ static inline int object_complete_ext(msgpack_unpacker_t* uk, int ext_type, VALU
|
|
191
209
|
}
|
192
210
|
|
193
211
|
/* stack funcs */
|
194
|
-
static inline
|
212
|
+
static inline msgpack_unpacker_stack_entry_t* _msgpack_unpacker_stack_entry_top(msgpack_unpacker_t* uk)
|
195
213
|
{
|
196
|
-
return &uk->stack[uk->
|
214
|
+
return &uk->stack->data[uk->stack->depth-1];
|
197
215
|
}
|
198
216
|
|
199
217
|
static inline int _msgpack_unpacker_stack_push(msgpack_unpacker_t* uk, enum stack_type_t type, size_t count, VALUE object)
|
200
218
|
{
|
201
219
|
reset_head_byte(uk);
|
202
220
|
|
203
|
-
if(uk->
|
221
|
+
if(uk->stack->capacity - uk->stack->depth <= 0) {
|
204
222
|
return PRIMITIVE_STACK_TOO_DEEP;
|
205
223
|
}
|
206
224
|
|
207
|
-
|
225
|
+
msgpack_unpacker_stack_entry_t* next = &uk->stack->data[uk->stack->depth];
|
208
226
|
next->count = count;
|
209
227
|
next->type = type;
|
210
228
|
next->object = object;
|
211
229
|
next->key = Qnil;
|
212
230
|
|
213
|
-
uk->
|
231
|
+
uk->stack->depth++;
|
214
232
|
return PRIMITIVE_CONTAINER_START;
|
215
233
|
}
|
216
234
|
|
217
235
|
static inline VALUE msgpack_unpacker_stack_pop(msgpack_unpacker_t* uk)
|
218
236
|
{
|
219
|
-
return --uk->
|
237
|
+
return --uk->stack->depth;
|
220
238
|
}
|
221
239
|
|
222
240
|
static inline bool msgpack_unpacker_stack_is_empty(msgpack_unpacker_t* uk)
|
223
241
|
{
|
224
|
-
return uk->
|
242
|
+
return uk->stack->depth == 0;
|
225
243
|
}
|
226
244
|
|
227
245
|
#ifdef USE_CASE_RANGE
|
@@ -249,8 +267,8 @@ static inline bool msgpack_unpacker_stack_is_empty(msgpack_unpacker_t* uk)
|
|
249
267
|
|
250
268
|
static inline bool is_reading_map_key(msgpack_unpacker_t* uk)
|
251
269
|
{
|
252
|
-
if(uk->
|
253
|
-
|
270
|
+
if(uk->stack->depth > 0) {
|
271
|
+
msgpack_unpacker_stack_entry_t* top = _msgpack_unpacker_stack_entry_top(uk);
|
254
272
|
if(top->type == STACK_TYPE_MAP_KEY) {
|
255
273
|
return true;
|
256
274
|
}
|
@@ -304,20 +322,14 @@ static inline int read_raw_body_begin(msgpack_unpacker_t* uk, int raw_type)
|
|
304
322
|
reset_head_byte(uk);
|
305
323
|
uk->reading_raw_remaining = 0;
|
306
324
|
|
307
|
-
msgpack_unpacker_stack_t*
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
uk->stack = _msgpack_unpacker_new_stack();
|
312
|
-
uk->stack_depth = 0;
|
313
|
-
uk->stack_capacity = MSGPACK_UNPACKER_STACK_CAPACITY;
|
325
|
+
msgpack_unpacker_stack_t* child_stack = _msgpack_unpacker_new_stack();
|
326
|
+
child_stack->parent = uk->stack;
|
327
|
+
uk->stack = child_stack;
|
314
328
|
|
315
329
|
obj = rb_funcall(proc, s_call, 1, uk->buffer.owner);
|
316
330
|
|
317
|
-
|
318
|
-
|
319
|
-
uk->stack_depth = stack_depth;
|
320
|
-
uk->stack_capacity = stack_capacity;
|
331
|
+
uk->stack = child_stack->parent;
|
332
|
+
_msgpack_unpacker_free_stack(child_stack);
|
321
333
|
|
322
334
|
return object_complete(uk, obj);
|
323
335
|
}
|
@@ -371,9 +383,6 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
371
383
|
|
372
384
|
SWITCH_RANGE(b, 0xa0, 0xbf) // FixRaw / fixstr
|
373
385
|
int count = b & 0x1f;
|
374
|
-
if(count == 0) {
|
375
|
-
return object_complete(uk, rb_utf8_str_new_static("", 0));
|
376
|
-
}
|
377
386
|
/* read_raw_body_begin sets uk->reading_raw */
|
378
387
|
uk->reading_raw_remaining = count;
|
379
388
|
return read_raw_body_begin(uk, RAW_TYPE_STRING);
|
@@ -390,7 +399,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
390
399
|
if(count == 0) {
|
391
400
|
return object_complete(uk, rb_hash_new());
|
392
401
|
}
|
393
|
-
return _msgpack_unpacker_stack_push(uk, STACK_TYPE_MAP_KEY, count*2,
|
402
|
+
return _msgpack_unpacker_stack_push(uk, STACK_TYPE_MAP_KEY, count*2, rb_hash_new_capa(count));
|
394
403
|
|
395
404
|
SWITCH_RANGE(b, 0xc0, 0xdf) // Variable
|
396
405
|
switch(b) {
|
@@ -473,7 +482,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
473
482
|
{
|
474
483
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
|
475
484
|
uint32_t u32 = _msgpack_be32(cb->u32);
|
476
|
-
return object_complete(uk, ULONG2NUM(
|
485
|
+
return object_complete(uk, ULONG2NUM(u32)); // long at least 32 bits
|
477
486
|
}
|
478
487
|
|
479
488
|
case 0xcf: // unsigned int 64
|
@@ -501,7 +510,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
501
510
|
{
|
502
511
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
|
503
512
|
int32_t i32 = _msgpack_be32(cb->i32);
|
504
|
-
return object_complete(uk, LONG2NUM(
|
513
|
+
return object_complete(uk, LONG2NUM(i32)); // long at least 32 bits
|
505
514
|
}
|
506
515
|
|
507
516
|
case 0xd3: // signed int 64
|
@@ -556,9 +565,6 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
556
565
|
{
|
557
566
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
|
558
567
|
uint8_t count = cb->u8;
|
559
|
-
if(count == 0) {
|
560
|
-
return object_complete(uk, rb_utf8_str_new_static("", 0));
|
561
|
-
}
|
562
568
|
/* read_raw_body_begin sets uk->reading_raw */
|
563
569
|
uk->reading_raw_remaining = count;
|
564
570
|
return read_raw_body_begin(uk, RAW_TYPE_STRING);
|
@@ -568,9 +574,6 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
568
574
|
{
|
569
575
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
|
570
576
|
uint16_t count = _msgpack_be16(cb->u16);
|
571
|
-
if(count == 0) {
|
572
|
-
return object_complete(uk, rb_utf8_str_new_static("", 0));
|
573
|
-
}
|
574
577
|
/* read_raw_body_begin sets uk->reading_raw */
|
575
578
|
uk->reading_raw_remaining = count;
|
576
579
|
return read_raw_body_begin(uk, RAW_TYPE_STRING);
|
@@ -580,9 +583,6 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
580
583
|
{
|
581
584
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
|
582
585
|
uint32_t count = _msgpack_be32(cb->u32);
|
583
|
-
if(count == 0) {
|
584
|
-
return object_complete(uk, rb_utf8_str_new_static("", 0));
|
585
|
-
}
|
586
586
|
/* read_raw_body_begin sets uk->reading_raw */
|
587
587
|
uk->reading_raw_remaining = count;
|
588
588
|
return read_raw_body_begin(uk, RAW_TYPE_STRING);
|
@@ -592,9 +592,6 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
592
592
|
{
|
593
593
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
|
594
594
|
uint8_t count = cb->u8;
|
595
|
-
if(count == 0) {
|
596
|
-
return object_complete(uk, rb_str_new_static("", 0));
|
597
|
-
}
|
598
595
|
/* read_raw_body_begin sets uk->reading_raw */
|
599
596
|
uk->reading_raw_remaining = count;
|
600
597
|
return read_raw_body_begin(uk, RAW_TYPE_BINARY);
|
@@ -604,9 +601,6 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
604
601
|
{
|
605
602
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
|
606
603
|
uint16_t count = _msgpack_be16(cb->u16);
|
607
|
-
if(count == 0) {
|
608
|
-
return object_complete(uk, rb_str_new_static("", 0));
|
609
|
-
}
|
610
604
|
/* read_raw_body_begin sets uk->reading_raw */
|
611
605
|
uk->reading_raw_remaining = count;
|
612
606
|
return read_raw_body_begin(uk, RAW_TYPE_BINARY);
|
@@ -616,9 +610,6 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
616
610
|
{
|
617
611
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
|
618
612
|
uint32_t count = _msgpack_be32(cb->u32);
|
619
|
-
if(count == 0) {
|
620
|
-
return object_complete(uk, rb_str_new_static("", 0));
|
621
|
-
}
|
622
613
|
/* read_raw_body_begin sets uk->reading_raw */
|
623
614
|
uk->reading_raw_remaining = count;
|
624
615
|
return read_raw_body_begin(uk, RAW_TYPE_BINARY);
|
@@ -651,7 +642,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
651
642
|
if(count == 0) {
|
652
643
|
return object_complete(uk, rb_hash_new());
|
653
644
|
}
|
654
|
-
return _msgpack_unpacker_stack_push(uk, STACK_TYPE_MAP_KEY, count*2,
|
645
|
+
return _msgpack_unpacker_stack_push(uk, STACK_TYPE_MAP_KEY, count*2, rb_hash_new_capa(count));
|
655
646
|
}
|
656
647
|
|
657
648
|
case 0xdf: // map 32
|
@@ -661,7 +652,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
661
652
|
if(count == 0) {
|
662
653
|
return object_complete(uk, rb_hash_new());
|
663
654
|
}
|
664
|
-
return _msgpack_unpacker_stack_push(uk, STACK_TYPE_MAP_KEY, count*2,
|
655
|
+
return _msgpack_unpacker_stack_push(uk, STACK_TYPE_MAP_KEY, count*2, rb_hash_new_capa(count));
|
665
656
|
}
|
666
657
|
|
667
658
|
default:
|
@@ -748,7 +739,7 @@ int msgpack_unpacker_read(msgpack_unpacker_t* uk, size_t target_stack_depth)
|
|
748
739
|
|
749
740
|
container_completed:
|
750
741
|
{
|
751
|
-
|
742
|
+
msgpack_unpacker_stack_entry_t* top = _msgpack_unpacker_stack_entry_top(uk);
|
752
743
|
switch(top->type) {
|
753
744
|
case STACK_TYPE_ARRAY:
|
754
745
|
rb_ary_push(top->object, uk->last_object);
|
@@ -798,7 +789,7 @@ int msgpack_unpacker_skip(msgpack_unpacker_t* uk, size_t target_stack_depth)
|
|
798
789
|
|
799
790
|
container_completed:
|
800
791
|
{
|
801
|
-
|
792
|
+
msgpack_unpacker_stack_entry_t* top = _msgpack_unpacker_stack_entry_top(uk);
|
802
793
|
|
803
794
|
/* this section optimized out */
|
804
795
|
// TODO object_complete still creates objects which should be optimized out
|
data/ext/msgpack/unpacker.h
CHANGED
@@ -27,6 +27,7 @@
|
|
27
27
|
|
28
28
|
struct msgpack_unpacker_t;
|
29
29
|
typedef struct msgpack_unpacker_t msgpack_unpacker_t;
|
30
|
+
typedef struct msgpack_unpacker_stack_t msgpack_unpacker_stack_t;
|
30
31
|
|
31
32
|
enum stack_type_t {
|
32
33
|
STACK_TYPE_ARRAY,
|
@@ -39,19 +40,22 @@ typedef struct {
|
|
39
40
|
enum stack_type_t type;
|
40
41
|
VALUE object;
|
41
42
|
VALUE key;
|
42
|
-
}
|
43
|
+
} msgpack_unpacker_stack_entry_t;
|
44
|
+
|
45
|
+
struct msgpack_unpacker_stack_t {
|
46
|
+
size_t depth;
|
47
|
+
size_t capacity;
|
48
|
+
msgpack_unpacker_stack_entry_t *data;
|
49
|
+
msgpack_unpacker_stack_t *parent;
|
50
|
+
};
|
43
51
|
|
44
52
|
#define MSGPACK_UNPACKER_STACK_SIZE (8+4+8+8) /* assumes size_t <= 64bit, enum <= 32bit, VALUE <= 64bit */
|
45
53
|
|
46
54
|
struct msgpack_unpacker_t {
|
47
55
|
msgpack_buffer_t buffer;
|
48
|
-
|
56
|
+
msgpack_unpacker_stack_t *stack;
|
49
57
|
unsigned int head_byte;
|
50
58
|
|
51
|
-
msgpack_unpacker_stack_t* stack;
|
52
|
-
size_t stack_depth;
|
53
|
-
size_t stack_capacity;
|
54
|
-
|
55
59
|
VALUE last_object;
|
56
60
|
|
57
61
|
VALUE reading_raw;
|
@@ -209,7 +209,7 @@ static VALUE Unpacker_read_array_header(VALUE self)
|
|
209
209
|
raise_unpacker_error(r);
|
210
210
|
}
|
211
211
|
|
212
|
-
return ULONG2NUM(size);
|
212
|
+
return ULONG2NUM(size); // long at least 32 bits
|
213
213
|
}
|
214
214
|
|
215
215
|
static VALUE Unpacker_read_map_header(VALUE self)
|
@@ -222,7 +222,7 @@ static VALUE Unpacker_read_map_header(VALUE self)
|
|
222
222
|
raise_unpacker_error((int)r);
|
223
223
|
}
|
224
224
|
|
225
|
-
return ULONG2NUM(size);
|
225
|
+
return ULONG2NUM(size); // long at least 32 bits
|
226
226
|
}
|
227
227
|
|
228
228
|
|
@@ -450,4 +450,3 @@ void MessagePack_Unpacker_module_init(VALUE mMessagePack)
|
|
450
450
|
|
451
451
|
rb_define_method(cMessagePack_Unpacker, "full_unpack", Unpacker_full_unpack, 0);
|
452
452
|
}
|
453
|
-
|
data/lib/msgpack/version.rb
CHANGED
data/msgpack.gemspec
CHANGED
data/spec/factory_spec.rb
CHANGED
@@ -474,6 +474,10 @@ describe MessagePack::Factory do
|
|
474
474
|
expect(roundtrip(:symbol)).to be :symbol
|
475
475
|
end
|
476
476
|
|
477
|
+
it 'works with empty symbol' do
|
478
|
+
expect(roundtrip(:"")).to be :""
|
479
|
+
end
|
480
|
+
|
477
481
|
it 'preserves encoding for ASCII symbols' do
|
478
482
|
expect(:symbol.encoding).to be Encoding::US_ASCII
|
479
483
|
expect(roundtrip(:symbol)).to be :symbol
|
@@ -583,6 +587,30 @@ describe MessagePack::Factory do
|
|
583
587
|
GC.stress = false
|
584
588
|
end
|
585
589
|
end
|
590
|
+
|
591
|
+
it 'does not crash in recursive extensions' do
|
592
|
+
my_hash_type = Class.new(Hash)
|
593
|
+
factory = MessagePack::Factory.new
|
594
|
+
factory.register_type(7,
|
595
|
+
my_hash_type,
|
596
|
+
packer: ->(value, packer) do
|
597
|
+
packer.write(value.to_h)
|
598
|
+
end,
|
599
|
+
unpacker: ->(unpacker) { my_hash_type.new(unpacker.read) },
|
600
|
+
recursive: true,
|
601
|
+
)
|
602
|
+
|
603
|
+
payload = factory.dump(
|
604
|
+
[my_hash_type.new]
|
605
|
+
)
|
606
|
+
|
607
|
+
begin
|
608
|
+
GC.stress = true
|
609
|
+
factory.load(payload)
|
610
|
+
ensure
|
611
|
+
GC.stress = false
|
612
|
+
end
|
613
|
+
end
|
586
614
|
end
|
587
615
|
|
588
616
|
describe 'DefaultFactory' do
|
data/spec/spec_helper.rb
CHANGED
@@ -20,7 +20,11 @@ require "msgpack/bigint"
|
|
20
20
|
if GC.respond_to?(:verify_compaction_references)
|
21
21
|
# This method was added in Ruby 3.0.0. Calling it this way asks the GC to
|
22
22
|
# move objects around, helping to find object movement bugs.
|
23
|
-
|
23
|
+
begin
|
24
|
+
GC.verify_compaction_references(double_heap: true, toward: :empty)
|
25
|
+
rescue NotImplementedError
|
26
|
+
# Some platforms don't support compaction
|
27
|
+
end
|
24
28
|
end
|
25
29
|
|
26
30
|
if GC.respond_to?(:auto_compact=)
|
data/spec/unpacker_spec.rb
CHANGED
@@ -707,6 +707,18 @@ describe MessagePack::Unpacker do
|
|
707
707
|
described_class.new(:freeze => true)
|
708
708
|
end
|
709
709
|
|
710
|
+
if (-"test").equal?(-"test") # RUBY_VERSION >= "2.5"
|
711
|
+
it 'dedups strings' do
|
712
|
+
interned_str = -"test"
|
713
|
+
roundtrip = MessagePack.unpack(MessagePack.pack(interned_str), freeze: true)
|
714
|
+
expect(roundtrip).to be interned_str
|
715
|
+
|
716
|
+
interned_str = -""
|
717
|
+
roundtrip = MessagePack.unpack(MessagePack.pack(interned_str), freeze: true)
|
718
|
+
expect(roundtrip).to be interned_str
|
719
|
+
end
|
720
|
+
end
|
721
|
+
|
710
722
|
it 'can freeze objects when using .unpack' do
|
711
723
|
parsed_struct = MessagePack.unpack(buffer, freeze: true)
|
712
724
|
parsed_struct.should == struct
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: msgpack
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.5.
|
4
|
+
version: 1.5.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sadayuki Furuhashi
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2022-
|
13
|
+
date: 2022-08-23 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: bundler
|
@@ -96,6 +96,20 @@ dependencies:
|
|
96
96
|
- - ">="
|
97
97
|
- !ruby/object:Gem::Version
|
98
98
|
version: '0'
|
99
|
+
- !ruby/object:Gem::Dependency
|
100
|
+
name: benchmark-ips
|
101
|
+
requirement: !ruby/object:Gem::Requirement
|
102
|
+
requirements:
|
103
|
+
- - "~>"
|
104
|
+
- !ruby/object:Gem::Version
|
105
|
+
version: 2.10.0
|
106
|
+
type: :development
|
107
|
+
prerelease: false
|
108
|
+
version_requirements: !ruby/object:Gem::Requirement
|
109
|
+
requirements:
|
110
|
+
- - "~>"
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: 2.10.0
|
99
113
|
description: MessagePack is a binary-based efficient object serialization library.
|
100
114
|
It enables to exchange structured objects between many languages like JSON. But
|
101
115
|
unlike JSON, it is very fast and small.
|
@@ -117,16 +131,7 @@ files:
|
|
117
131
|
- README.md
|
118
132
|
- Rakefile
|
119
133
|
- appveyor.yml
|
120
|
-
- bench/
|
121
|
-
- bench/pack_log.rb
|
122
|
-
- bench/pack_log_long.rb
|
123
|
-
- bench/pack_symbols.rb
|
124
|
-
- bench/run.sh
|
125
|
-
- bench/run_long.sh
|
126
|
-
- bench/run_symbols.sh
|
127
|
-
- bench/unpack.rb
|
128
|
-
- bench/unpack_log.rb
|
129
|
-
- bench/unpack_log_long.rb
|
134
|
+
- bench/bench.rb
|
130
135
|
- doclib/msgpack.rb
|
131
136
|
- doclib/msgpack/buffer.rb
|
132
137
|
- doclib/msgpack/core_ext.rb
|
@@ -231,7 +236,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
231
236
|
- !ruby/object:Gem::Version
|
232
237
|
version: '0'
|
233
238
|
requirements: []
|
234
|
-
rubygems_version: 3.
|
239
|
+
rubygems_version: 3.1.2
|
235
240
|
signing_key:
|
236
241
|
specification_version: 4
|
237
242
|
summary: MessagePack, a binary-based efficient data interchange format.
|
data/bench/pack.rb
DELETED
@@ -1,23 +0,0 @@
|
|
1
|
-
require 'viiite'
|
2
|
-
require 'msgpack'
|
3
|
-
|
4
|
-
data = { 'hello' => 'world', 'nested' => ['structure', {value: 42}] }
|
5
|
-
data_sym = { hello: 'world', nested: ['structure', {value: 42}] }
|
6
|
-
|
7
|
-
data = MessagePack.pack(:hello => 'world', :nested => ['structure', {:value => 42}])
|
8
|
-
|
9
|
-
Viiite.bench do |b|
|
10
|
-
b.range_over([10_000, 100_000, 1000_000], :runs) do |runs|
|
11
|
-
b.report(:strings) do
|
12
|
-
runs.times do
|
13
|
-
MessagePack.pack(data)
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
b.report(:symbols) do
|
18
|
-
runs.times do
|
19
|
-
MessagePack.pack(data_sym)
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
data/bench/pack_log.rb
DELETED
@@ -1,33 +0,0 @@
|
|
1
|
-
require 'viiite'
|
2
|
-
require 'msgpack'
|
3
|
-
|
4
|
-
data_plain = { 'message' => '127.0.0.1 - - [10/Oct/2000:13:55:36 -0700] "GET /apache_pb.gif HTTP/1.0" 200 2326 "http://www.example.com/start.html" "Mozilla/4.08 [en] (Win98; I ;Nav)"' }
|
5
|
-
data_structure = {
|
6
|
-
'remote_host' => '127.0.0.1',
|
7
|
-
'remote_user' => '-',
|
8
|
-
'date' => '10/Oct/2000:13:55:36 -0700',
|
9
|
-
'request' => 'GET /apache_pb.gif HTTP/1.0',
|
10
|
-
'method' => 'GET',
|
11
|
-
'path' => '/apache_pb.gif',
|
12
|
-
'protocol' => 'HTTP/1.0',
|
13
|
-
'status' => 200,
|
14
|
-
'bytes' => 2326,
|
15
|
-
'referer' => 'http://www.example.com/start.html',
|
16
|
-
'agent' => 'Mozilla/4.08 [en] (Win98; I ;Nav)',
|
17
|
-
}
|
18
|
-
|
19
|
-
Viiite.bench do |b|
|
20
|
-
b.range_over([10_000, 100_000, 1000_000], :runs) do |runs|
|
21
|
-
b.report(:plain) do
|
22
|
-
runs.times do
|
23
|
-
MessagePack.pack(data_plain)
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
b.report(:structure) do
|
28
|
-
runs.times do
|
29
|
-
MessagePack.pack(data_structure)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
data/bench/pack_log_long.rb
DELETED
@@ -1,65 +0,0 @@
|
|
1
|
-
# viiite report --regroup bench,threads bench/pack_log_long.rb
|
2
|
-
|
3
|
-
require 'viiite'
|
4
|
-
require 'msgpack'
|
5
|
-
|
6
|
-
data_plain = { 'message' => '127.0.0.1 - - [10/Oct/2000:13:55:36 -0700] "GET /apache_pb.gif HTTP/1.0" 200 2326 "http://www.example.com/start.html" "Mozilla/4.08 [en] (Win98; I ;Nav)"' }
|
7
|
-
data_structure = {
|
8
|
-
'remote_host' => '127.0.0.1',
|
9
|
-
'remote_user' => '-',
|
10
|
-
'date' => '10/Oct/2000:13:55:36 -0700',
|
11
|
-
'request' => 'GET /apache_pb.gif HTTP/1.0',
|
12
|
-
'method' => 'GET',
|
13
|
-
'path' => '/apache_pb.gif',
|
14
|
-
'protocol' => 'HTTP/1.0',
|
15
|
-
'status' => 200,
|
16
|
-
'bytes' => 2326,
|
17
|
-
'referer' => 'http://www.example.com/start.html',
|
18
|
-
'agent' => 'Mozilla/4.08 [en] (Win98; I ;Nav)',
|
19
|
-
}
|
20
|
-
|
21
|
-
seconds = 3600 # 1 hour
|
22
|
-
|
23
|
-
Viiite.bench do |b|
|
24
|
-
b.range_over([1, 2, 4, 8, 16], :threads) do |threads|
|
25
|
-
b.report(:plain) do
|
26
|
-
ths = []
|
27
|
-
end_at = Time.now + seconds
|
28
|
-
threads.times do
|
29
|
-
t = Thread.new do
|
30
|
-
packs = 0
|
31
|
-
while Time.now < end_at
|
32
|
-
10000.times do
|
33
|
-
MessagePack.pack(data_plain)
|
34
|
-
end
|
35
|
-
packs += 10000
|
36
|
-
end
|
37
|
-
packs
|
38
|
-
end
|
39
|
-
ths.push t
|
40
|
-
end
|
41
|
-
sum = ths.reduce(0){|r,t| r + t.value }
|
42
|
-
puts "MessagePack.pack, plain, #{threads} threads: #{sum} times, #{sum / seconds} times/second."
|
43
|
-
end
|
44
|
-
|
45
|
-
b.report(:structure) do
|
46
|
-
ths = []
|
47
|
-
end_at = Time.now + seconds
|
48
|
-
threads.times do
|
49
|
-
t = Thread.new do
|
50
|
-
packs = 0
|
51
|
-
while Time.now < end_at
|
52
|
-
10000.times do
|
53
|
-
MessagePack.pack(data_structure)
|
54
|
-
end
|
55
|
-
packs += 10000
|
56
|
-
end
|
57
|
-
packs
|
58
|
-
end
|
59
|
-
ths.push t
|
60
|
-
end
|
61
|
-
sum = ths.reduce(0){|r,t| r + t.value }
|
62
|
-
puts "MessagePack.pack, structured, #{threads} threads: #{sum} times, #{sum / seconds} times/second."
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
data/bench/pack_symbols.rb
DELETED
@@ -1,28 +0,0 @@
|
|
1
|
-
require 'viiite'
|
2
|
-
require 'msgpack'
|
3
|
-
|
4
|
-
data = :symbol
|
5
|
-
|
6
|
-
Viiite.bench do |b|
|
7
|
-
b.variation_point :branch, `git rev-parse --abbrev-ref HEAD`
|
8
|
-
|
9
|
-
b.range_over([:symbol, :none], :reg_type) do |reg_type|
|
10
|
-
packer = MessagePack::Packer.new
|
11
|
-
packer.register_type(0x00, Symbol, :to_msgpack_ext) if reg_type == :symbol
|
12
|
-
|
13
|
-
b.range_over([100_000, 1_000_000, 10_000_000], :count) do |count|
|
14
|
-
packer.clear
|
15
|
-
b.report(:multi_run) do
|
16
|
-
count.times do
|
17
|
-
packer.pack(data)
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
packer.clear
|
22
|
-
items_data = [].fill(data, 0, count)
|
23
|
-
b.report(:large_run) do
|
24
|
-
packer.pack(items_data)
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|